package com.mes.schedule.manager;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.ExecutorService;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom2.Element;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.mes.basicdata.dao.DeptDao;
import com.mes.basicdata.dao.DeviceDao;
import com.mes.basicdata.domain.CalendarData;
import com.mes.basicdata.domain.Dept;
import com.mes.common.exception.bo.BaseBusinessException;
import com.mes.common.exception.db.BaseDBException;
import com.mes.common.model.ObjectOperation;
import com.mes.common.spring.SpringUtils;
import com.mes.common.util.SysUtil;
import com.mes.schedule.dao.DemandSTaskLinkDao;
import com.mes.schedule.dao.SPartTaskDao;
import com.mes.schedule.dao.STaskDao;
import com.mes.schedule.dao.ScheduleSchemeDao;
import com.mes.schedule.domain.DemandSTaskLink;
import com.mes.schedule.domain.McDevice;
import com.mes.schedule.domain.ResourceConstraint;
import com.mes.schedule.domain.SDevice;
import com.mes.schedule.domain.SOperationLink;
import com.mes.schedule.domain.SOperationTask;
import com.mes.schedule.domain.SPartTask;
import com.mes.schedule.domain.SVirtualLink;
import com.mes.schedule.domain.ScheduleScheme;
import com.mes.schedule.domain.SchemeActiveControl;
import com.mes.schedule.domain.UcDevice;
import com.mes.schedule.util.ScheduleUtils;
import com.mes.schedule.util.StringOper;

/**
 * 
 * ClassName: ScheduleSchemeManager <br/> Function: 调度方案管理 <br/> date: Mar 29,
 * 2015 11:03:26 AM <br/>
 * 
 * @author LQM
 * @version
 * @since JDK 1.6
 */
@Component("scheduleSchemeManager")
@Transactional
public class ScheduleSchemeManager{
	private final static Log log = LogFactory
			.getLog(ScheduleSchemeManager.class);
	@javax.annotation.Resource
	private ScheduleManager scheduleManager;
	@javax.annotation.Resource
	private ScheduleSchemeDao scheduleDao;
	@javax.annotation.Resource
	private SPartTaskDao schedulePartTaskDao;
	@javax.annotation.Resource
	private SchedulePartTaskManager schedulePartTaskManager;
	@javax.annotation.Resource
	private ScheduleDeviceManager scheduledeviceManager;
	@javax.annotation.Resource
	private ScheduleOperationTaskManager scheduleOperationTaskManager;
	@javax.annotation.Resource
	private ScheduleLinkManager scheduleLinkManager;
	@javax.annotation.Resource
	private ScheduleSyncManager scheduleSyncManager;
	@javax.annotation.Resource
	private STaskDao scheduleTaskDao;
	@javax.annotation.Resource
	private DeviceDao deviceDao;
	@javax.annotation.Resource
	public ScheduleEventManager scheduleEventManager;
	@javax.annotation.Resource
	public ScheduleOperationRecordManager scheduleOperationRecordManager;

	@javax.annotation.Resource
	public ScheduleSchemeDao scheduleSchemeDao;
	
	private Map<String, SchemeActiveControl> schemeMap = new HashMap<String, SchemeActiveControl>();
	protected Integer maxSchemeIdleMinutes;

	/**
	 * 部门对应的调度器方案编号集合
	 */
	private Map<String, Set<String>> deptSchemeUidMap = new HashMap<String, Set<String>>();

	/**
	 * 返回调度方案编号集合 *
	 * 
	 * @param masterShopUid
	 * @return
	 */
	public Set<String> getSchemeUidSet(String masterShopUid) {
		if (deptSchemeUidMap.containsKey(masterShopUid)) {
			return deptSchemeUidMap.get(masterShopUid);
		}

		Set<String> schemeUidSet = new HashSet<String>();
		List<ScheduleScheme> schemes = scheduleDao
				.getCapcitySchemes(masterShopUid);
		if (schemes != null && schemes.size() > 0) {
			for (ScheduleScheme scheme : schemes) {
				schemeUidSet.add(scheme.getScheduleUid());
			}
			deptSchemeUidMap.put(masterShopUid, schemeUidSet);
			return schemeUidSet;

		}

		return null;
	}

	/**
	 * 取得处于激活状态的调度方案
	 * 
	 * @param scheduleUid
	 * @throws Exception
	 */
	public List<ScheduleScheme> getActiveSchemes() throws Exception {
		List<ScheduleScheme> activeSchemes = new ArrayList<ScheduleScheme>();
		try {

			Iterator<SchemeActiveControl> iterator = schemeMap.values()
					.iterator();
			while (iterator.hasNext()) {
				SchemeActiveControl schemeActiveControl = iterator.next();
				if (schemeActiveControl.getActiveState() == SchemeActiveControl.SCHEME_STATE_ACTIVE) {
					activeSchemes.add(schemeActiveControl.getScheme());
					// 每次访问都设置当前活动时间
					// 防止被自动idle程序清除
					schemeActiveControl.setLastActiveTime(new Date());
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// 只返回已激活状态的方案集合
		return activeSchemes;
	}

	/**
	 * 所有外部类获取scheme都应该采用此方法
	 * 
	 * @param scheduleUid
	 * @return
	 * @throws Exception
	 */
	public void autoSchemeIdlePro() {
		try {
			log.info("调度方案定时闲置处理开始！");
			if (maxSchemeIdleMinutes == null)
				maxSchemeIdleMinutes = 15;
			Iterator<SchemeActiveControl> iterator = schemeMap.values()
					.iterator();
			while (iterator.hasNext()) {
				SchemeActiveControl schemeActiveControl = iterator.next();
				Date currentTime = new Date();
				int idleTime = (int) (currentTime.getTime() - schemeActiveControl
						.getLastActiveTime().getTime())
						/ ScheduleUtils.MillSecondsOfMinute;

				if (schemeActiveControl.getActiveState() == SchemeActiveControl.SCHEME_STATE_ACTIVE
						&& idleTime > maxSchemeIdleMinutes) {
					ScheduleScheme scheme = schemeActiveControl.getScheme();
					log.info("调度方案闲置处理开始！" + scheme.getScheduleUid());

					if (scheme.getPersistence())
						this.idleScheme(scheme.getScheduleUid());
					else {
						iterator.remove(); // 用iterator避免并行问题
					}

					// schemeActiveControl.setActiveState(SchemeActiveControl.SCHEME_STATE_IDLE);

				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * 所有外部类获取scheme都应该采用此方法
	 * 
	 * @param scheduleUid
	 * @return
	 * @throws Exception
	 */
	// 在get方法中注意增加了restoreScheme功能
	// 就要避免springconfig中定义的get方法只读事务问题,将其改成不支持事务
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public ScheduleScheme getScheduleScheme(String scheduleUid) {
		// 仅用于加密
		// Calendar c=Calendar.getInstance();
		// Date currentTime=c.getTime();
		// c.set(2015, 0, 30);
		// if(currentTime.after(c.getTime()))
		// {
		// return null;
		// }

		// log.error("****************************************lqm todo");
		if (scheduleUid == null)
			return null;
		ScheduleScheme scheme = null;
		try {
			SchemeActiveControl schemeActiveControl = schemeMap
					.get(scheduleUid);
			if (schemeActiveControl != null) {
				// 处于idle状态自动打开
				if (schemeActiveControl.getActiveState() == SchemeActiveControl.SCHEME_STATE_IDLE) {
					// 自动重新打开
					// 注意scheme==null时，有可能会报错
					// 造成过比较严重的线上bug
					// if (scheme==null || scheme.getPersistence())// 必须是持久化的
					// lqm todo
					scheme = this.restoreScheme(scheduleUid);
					schemeActiveControl.setScheme(scheme);
					schemeActiveControl
							.setActiveState(SchemeActiveControl.SCHEME_STATE_ACTIVE);
				}
				// 每次访问都设置当前活动时间
				schemeActiveControl.setLastActiveTime(new Date());
				scheme = schemeActiveControl.getScheme();
			}
			// if (scheme == null) {
			// // throw new Exception("调度方案不存在或者未打开！");
			// }
		} catch (Exception e) {
			log.error(e);
		}
		return scheme;
	}

	/**
	 * 判断一个调度方案是否打开
	 */
	public void restoreSchemeFromSnapShot(String scheduleUid,
			ScheduleScheme snapShotScheme) {
		try {
			this.removeScheme(scheduleUid);
			snapShotScheme.setScheduleUid(scheduleUid);
			this.addScheme(snapShotScheme);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 判断一个调度方案是否打开
	 */
	public boolean isOpened(String scheduleUid) {
		return schemeMap.containsKey(scheduleUid);
	}

	/**
	 * 获取调度方案的类型 by hba
	 * 
	 * @param scheduleUid
	 * @return
	 * @throws Exception 
	 */
	public String getSchemeType(String scheduleUid) throws Exception {

		ScheduleScheme scheduleScheme = (ScheduleScheme) scheduleSchemeDao.getById(scheduleUid);
		if (scheduleScheme != null) {
			return scheduleScheme.getSchemeType();
		}
		return null;
	}

	/**
	 * 获取调度方案的名称 by hba
	 * 
	 * @param scheduleUid
	 * @return
	 * @throws Exception 
	 */
	public String getSchemeName(String scheduleUid) throws Exception {

		ScheduleScheme scheduleScheme = (ScheduleScheme) scheduleManager.getById(scheduleUid);
		if (scheduleScheme != null) {
			return scheduleScheme.getScheduleName();
		}
		return null;
	}

	/**
	 * 判断一个调度方案是否打开
	 */
	public boolean isSchemeCreated(String deptUid) throws Exception {
		if (deptUid == null)
			throw new Exception("部门编号为空，请重新登录!");
		try {
			String scheduleUid = ScheduleUtils.getScheduleUid(deptUid);
			ScheduleScheme scheduleScheme = (ScheduleScheme) scheduleSchemeDao
					.getById(scheduleUid);
			if (scheduleScheme != null)
				return true;
		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;

	}

	/**
	 * @param scheduleManager
	 *            the scheduleManager to set
	 */
	public void setScheduleManager(ScheduleManager scheduleManager) {
		this.scheduleManager = scheduleManager;
	}

	/*
	 * 
	 */

	/**
	 * @param schedulePartTaskManager
	 *            the schedulePartTaskManager to set
	 */
	public void setSchedulePartTaskManager(
			SchedulePartTaskManager schedulePartTaskManager) {
		this.schedulePartTaskManager = schedulePartTaskManager;
	}

	/**
	 * @param deviceManager
	 *            the deviceManager to set
	 */
	public void setDeviceManager(ScheduleDeviceManager scheduledeviceManager) {
		this.scheduledeviceManager = scheduledeviceManager;
	}

	/**
	 * @param scheduleOperationTaskManager
	 *            the scheduleOperationTaskManager to set
	 */
	public void setScheduleOperationTaskManager(
			ScheduleOperationTaskManager scheduleOperationTaskManager) {
		this.scheduleOperationTaskManager = scheduleOperationTaskManager;
	}

	/**
	 * @param scheduleTaskDao
	 *            the scheduleTaskDao to set
	 */
	public void setScheduleTaskDao(STaskDao scheduleTaskDao) {
		this.scheduleTaskDao = scheduleTaskDao;
	}

	/**
	 * @param deviceDao
	 *            the deviceDao to set
	 */
	public void setDeviceDao(DeviceDao deviceDao) {
		this.deviceDao = deviceDao;
	}

	/**
	 * 从数据库中获取调度方案
	 * 
	 * @param scheduleUid
	 * @return ScheduleScheme
	 * @throws Exception
	 */
	public ScheduleScheme loadScheduleScheme(String scheduleUid)
			throws Exception {
		ScheduleScheme scheme = null;
		if (scheduleUid == null || scheduleUid.equals("")) {
			throw new Exception("调度方案编号不能为空!");
		}

		// scheme = getScheduleScheme(scheduleUid);
		// if (scheme == null) {
		scheme = scheduleManager.getScheduleByUid(scheduleUid);
		// schemeMap.put(scheduleUid, scheme);
		// }

		return scheme;
	}

	/**
	 * saving the changes after creating a new schedule scheme or changing the
	 * parameters of the current schedule scheme
	 * 
	 * @param scheme
	 * @throws Exception 
	 */
	public void saveScheme(ScheduleScheme scheme) throws Exception {
		// beanUtils = new BeanUtils();

		if (schemeMap.containsKey(scheme.getScheduleUid())) {
			// change happened
			ScheduleScheme oldScheme = getScheduleScheme(scheme
					.getScheduleUid());
			ObjectOperation.copyAttributes(scheme, oldScheme);
			// scheme.setRemainPartTaskList(oldScheme.getRemainPartTaskList());

			// scheme.setAllPartTaskMap(oldScheme.getAllPartTaskMap());
			//
			// scheme.setSplitedPartTaskList(oldScheme.getSplitedPartTaskList());
			//
			// scheme.setSingleOperationList(oldScheme.getSingleOperationList());
			// scheme.setDeviceMap(oldScheme.getDeviceMap());
			// scheme.setGroupTaskList(oldScheme.getGroupTaskList());
			//
			// scheme.setCalendarMap(oldScheme.getCalendarMap());
			// beanUtils.copyProperties(oldScheme, scheme);
			this.scheduleManager.update(oldScheme);

		} else {
			// new created
			this.scheduleManager.save(scheme);
			// schemeMap.put(scheme.getScheduleUid(), scheme);
		}
	}

	/**
	 * create the task net
	 * 
	 * @param scheduleUid
	 * @param deptId
	 * @throws BaseDBException
	 */
	public void importTasks(String scheduleUid, String deptId) throws Exception {

		ScheduleScheme scheme = loadScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}
		this.scheduleManager.importTasks(scheme);
		SchemeActiveControl schemeActiveControl = new SchemeActiveControl();
		schemeActiveControl.setScheme(scheme);
		schemeActiveControl.setLastActiveTime(new Date());
		schemeActiveControl
				.setActiveState(SchemeActiveControl.SCHEME_STATE_ACTIVE);
		schemeMap.put(scheme.getScheduleUid(), schemeActiveControl);
	}

	public void applySchedulePara(ScheduleScheme scheme) throws Exception {

		ScheduleScheme originScheme = getScheduleScheme(scheme.getScheduleUid());
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}
		scheduleManager.applySchedulePara(scheme, originScheme);

	}

	/**
	 * the entrance of the main schedule process
	 */
	public void doSchedule(String scheduleUid, int mode) throws Exception {

		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}
		scheduleManager.doSchedule(scheme, mode);
	}

	/**
	 * haven't checked
	 * 
	 * @param scheme
	 * @throws Exception 
	 */
	public void finishScheme(ScheduleScheme scheme) throws Exception {
		if (schemeMap.containsKey(scheme.getScheduleUid())) {
			scheduleManager.finishScheme(scheme);
			schemeMap.remove(scheme.getScheduleUid());
		} else {
			throw new BaseDBException("Error!");
		}
	}

	/**
	 * save a schedule scheme, haven't checked
	 * 
	 * @param scheduleUid
	 * @throws Exception
	 */
	public void saveResult(String scheduleUid) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}
		scheduleManager.saveResult(scheme);
	}

	/**
	 * add by zy save a schedule scheme, haven't checked and set current is
	 * true,other is false
	 * 
	 * @param scheduleUid
	 * @throws Exception
	 */
	public void submitScheme(String scheduleUid, String deptId)
			throws Exception {
		List<ScheduleScheme> schemeList = this.scheduleDao
				.getSchemesByDeptId(deptId);
		ScheduleScheme schemeCurrent = getScheduleScheme(scheduleUid);
		if (schemeCurrent == null || schemeList == null) {
			throw new Exception("请先打开调度方案!");
		} else {
			for (ScheduleScheme scheme : schemeList) {
				if (schemeCurrent.getScheduleUid().equals(
						scheme.getScheduleUid())) {
					scheme.setEffective(true);
				} else {
					scheme.setEffective(false);
				}

				this.scheduleManager.update(scheme);
			}
		}

		scheduleManager.saveResult(schemeCurrent);

	}

	/**
	 * close a schedule scheme 闲置任务处理
	 * 
	 * @param scheduleUid
	 * @throws Exception
	 */
	public void idleScheme(String scheduleUid) throws Exception {
		SchemeActiveControl schemeActiveControl = schemeMap.get(scheduleUid);

		if (schemeActiveControl == null
				|| schemeActiveControl.getActiveState() == SchemeActiveControl.SCHEME_STATE_IDLE) {
			return;
		}
		ScheduleScheme scheme = schemeActiveControl.getScheme();
		if (scheme == null) {
			log.warn("该调度方案已经关闭！");
		}
		// lqm todo
		// 以后应该用更好的idle处理方法
		// 可将scheme 放到一个文件中
		log.info("开始关闭调度方案" + scheduleUid);
		// 如果有正在进行的调度进程
		// 立即关闭
		// lqm todo
		// 将来如何容纳长周期算法
		try {
			ExecutorService executorService = ScheduleUtils
					.getExecutorService(scheme);
			if (executorService != null && !executorService.isShutdown()) {
				// log.warn("发现调度算法正在运行，退出闲置处理！");
				// return;
				executorService.shutdownNow();
			}

		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.scheduleManager.destroyScheme(scheme);

		if (scheme.getPersistence()) {
			schemeActiveControl
					.setActiveState(SchemeActiveControl.SCHEME_STATE_IDLE);
			schemeActiveControl.setScheme(null);
		}

		scheme = null;
		log.info("结束关闭调度方案" + scheduleUid);
	}

	/**
	 * close a schedule scheme
	 * 
	 * @param scheduleUid
	 * @throws Exception
	 */
	public void closeScheme(String scheduleUid) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("该调度方案已经关闭！");
		}
		log.info("开始关闭调度方案" + scheduleUid);
		// 如果有正在进行的调度进程
		// 立即关闭
		try {
			ExecutorService executorService = ScheduleUtils
					.getExecutorService(scheme);
			if (executorService != null && !executorService.isShutdown())
				executorService.shutdownNow();
		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		this.scheduleManager.destroyScheme(scheme);

		schemeMap.remove(scheduleUid);
		scheme = null;
		log.info("结束关闭调度方案" + scheduleUid);
	}

	/**
	 * restore a schedule scheme
	 * 
	 * @param scheduleUid
	 * @throws Exception
	 */
	public ScheduleScheme restoreScheme(String scheduleUid) throws Exception {
		ScheduleScheme scheme = loadScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请确认该调度方案是否存在!");
		}
		scheduleManager.restoreScheme(scheme);

		this.addScheme(scheme);
		return scheme;

	}

	/**
	 * 将调度方案添加进Map中
	 */
	public void addScheme(ScheduleScheme scheme) {
			
		try{
			SchemeActiveControl schemeActiveControl = new SchemeActiveControl();
			schemeActiveControl.setScheme(scheme);
			schemeActiveControl.setLastActiveTime(new Date());
			schemeActiveControl
			.setActiveState(SchemeActiveControl.SCHEME_STATE_ACTIVE);
			schemeMap.put(scheme.getScheduleUid(), schemeActiveControl);
		}catch(Exception e){
			e.printStackTrace();
		}

	}

	/**
	 * 获取活动的调度方案 如果没有泽激活
	 * 
	 * @param scheduleUid
	 * @throws Exception
	 */
	public ScheduleScheme getActiveScheme(String scheduleUid) throws Exception {
		if (scheduleUid == null)
			return null;
		if (!(schemeMap.containsKey(scheduleUid)))
			this.restoreScheme(scheduleUid);

		return getScheduleScheme(scheduleUid);

	}

	/**
	 * 获取活动的调度方案
	 * 
	 * @param scheduleUid
	 * @throws Exception
	 */
	public List<ScheduleScheme> getDeptActiveSchemes(String deptUid)
			throws Exception {
		List<ScheduleScheme> activeSchemes = new ArrayList<ScheduleScheme>();

		List<SchemeActiveControl> schemeActiveControls = new ArrayList<SchemeActiveControl>();

		for (SchemeActiveControl schemeActiveControl : this.schemeMap.values()) {
			ScheduleScheme scheme = schemeActiveControl.getScheme();

			if (scheme != null && scheme.getDeptUid().startsWith(deptUid)) {
				schemeActiveControls.add(schemeActiveControl);

			}
		}

		// 按照逆序排列
		Collections.sort(schemeActiveControls, new Comparator<Object>() {
			public int compare(Object o1, Object o2) {
				SchemeActiveControl schemeActiveControl1 = (SchemeActiveControl) o1;
				SchemeActiveControl SchemeActiveControl2 = (SchemeActiveControl) o2;
				int i = 0;
				// 都是锁定的情况下
				// 优先级越大表示越不重要
				// 同等优先级松弛率越大表示越不重要
				if (schemeActiveControl1.getLastActiveTime().before(
						SchemeActiveControl2.getLastActiveTime())) {
					i = 1;
				}
				return i;
			}
		});

		for (SchemeActiveControl schemeActiveControl : schemeActiveControls) {

			activeSchemes.add(schemeActiveControl.getScheme());
		}

		return activeSchemes;

	}

	/**
	 * 打开调度方案
	 * 
	 * @param scheduleUid
	 * @throws Exception
	 */
	@Transactional
	public void openScheme(String scheduleUid) throws Exception {
		ScheduleScheme scheme = loadScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("无法找到调度方案!");
		}

		String operatorUid = "";//SysUtil.getSessionEmployeeId();
		scheme.setCreatorUid(operatorUid);

		//EmployeeManager employeeManager = (EmployeeManager) SpringUtils
		//		.getBean("employeeManager");
		//Employee operator = (Employee) employeeManager.getById(operatorUid);
		//if (operator == null) {
		//	throw new Exception("根据员工编号无法找到操作者" + operator);
		//}
		//scheme.setCreator(operator);

		scheduleManager.restoreScheme(scheme);
		this.addScheme(scheme);
		//会报错
	}

	// public String syncScheme(String scheduleUid) throws BaseBusinessException
	// {
	// ScheduleScheme scheme = getScheduleScheme(scheduleUid);
	// if (scheme == null) {
	// throw new BaseBusinessException("该调度方案不存在或者还未打开！");
	// }
	// try {
	// return scheduleSyncManager.syncScheme(scheme);
	// } catch (Exception e) {
	// // TODO Auto-generated catch block
	// log.error(e.getMessage());
	// throw new BaseBusinessException("计划同步时发生错误！");
	// }
	//
	// }

	public String publishScheme(String scheduleUid, String publishType)
			throws BaseBusinessException {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new BaseBusinessException("该调度方案不存在或者还未打开！");
		}
		try {
			return scheduleSyncManager.publishScheme(scheme, publishType);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			log.error(e.getMessage());
			throw new BaseBusinessException("计划发布时发生错误！");
		}

	}

	/**
	 * get all part task in the schedule scheme
	 * 
	 * @param scheduleUid
	 * @return
	 * @throws Exception
	 */
	public Set<SPartTask> getPartTasks(String scheduleUid) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}
		return scheme.getSchedulePartTasks();
	}

	/**
	 * get the part task of the schedule scheme by taskuid
	 * 
	 * @param scheduleUid
	 * @param taskUid
	 * @return
	 * @throws Exception
	 */
	public SPartTask getPartTask(String scheduleUid, String taskUid)
			throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}

		return scheme.getAllPartTaskMap().get(taskUid);

	}

	/**
	 * add by zy get the part task of the schedule scheme by partUid
	 * 
	 * @param scheduleUid
	 * @param partUid
	 * @return
	 * @throws Exception
	 */
	public List<SPartTask> getPartTaskByPartUid(String scheduleUid,
			String partUid) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}

		List<SPartTask> partTaskList = new ArrayList<SPartTask>();
		// 应该从调度任务集合中获取 hba
		for (SPartTask partTask : scheme.getSchedulePartTasks()) {
			if (partTask.getPartUid() != null && partUid != null) {

				if (partTask.getPartUid().equals(partUid)
						&& partTask.getTaskState() < 106) {

					// SPartTask temp = this.schedulePartTaskDao
					// .getSchedulePartTask(scheduleUid, partTask
					// .getTaskUid());
					// if (partTask.getDemandLinkQty() == null) {
					// partTask.setDemandLinkQty(temp.getDemandLinkQty());
					// }
					partTaskList.add(partTask);

				}
			}

		}

		return partTaskList;

	}

	/**
	 * filter the part tasks according to the conditions with flag=0 schedule
	 * part tasks and flag=1 remain part tasks
	 * 
	 * @param parameters
	 * @param flag
	 * @return
	 * @throws Exception
	 */
	public List<SPartTask> partTaskFilter(String scheduleUid, Map parameters,
			int flag) throws Exception {

		List<SPartTask> partTaskList = null;
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			// scheme = scheduleManager.getScheduleByUid(scheduleUid);
			// schemeMap.put(scheduleUid, scheme);
		} else {
			if (scheme.getAllPartTaskMap() != null) {
				if (0 == flag) {

					partTaskList = this.schedulePartTaskManager.filter(scheme
							.getSchedulePartTasks(), parameters);
				} else {
					List<SPartTask> waitingPartTaskList = new ArrayList<SPartTask>();
					for (SPartTask sp : scheme.getAllPartTaskMap().values()) {
						if (sp.getTaskScheduleState() == SPartTask.TASKSCHEDULESTATE_WAITING)
							waitingPartTaskList.add(sp);
					}
					partTaskList = this.schedulePartTaskManager.filter(
							waitingPartTaskList, parameters);

				}

			}
		}
		// this.schedulePartTaskManager.sortByPriorityAndSlack(partTaskList);
		this.schedulePartTaskManager.sortByDrawingIdAndBatchNum(partTaskList);
		// 按优先级和松弛率排序临建
		// this.schedulePartTaskManager.sortByPriorityAndSlack(partTaskList);

		return partTaskList;
	}

	public List<SPartTask> partTaskFilter(String scheduleUid, Map parameters)
			throws Exception {

		List<SPartTask> partTaskList = null;
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			// scheme = scheduleManager.getScheduleByUid(scheduleUid);
			// schemeMap.put(scheduleUid, scheme);
		} else {
			if (scheme.getAllPartTaskMap() != null) {
				partTaskList = this.schedulePartTaskManager.filterPrecise(
						scheme.getSchedulePartTasks(), parameters);
			}
		}
		// this.schedulePartTaskManager.sortByPriorityAndSlack(partTaskList);
		this.schedulePartTaskManager.sortByDrawingIdAndBatchNum(partTaskList);
		// 按优先级和松弛率排序临建
		// this.schedulePartTaskManager.sortByPriorityAndSlack(partTaskList);
		return partTaskList;
	}

	/**
	 * get the operation tasks for the resource gantt chart within the utilize
	 * days
	 * 
	 * @param scheduleUid
	 * @return
	 * @throws Exception
	 */
	public List<SOperationTask> getGanttOperationTaskList(String scheduleUid)
			throws Exception {

		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			// throw new Exception("请先打开调度方案!");
			return null;
		}

		List<SOperationTask> operationTaskList = null;
		Calendar temp = Calendar.getInstance();
		temp.setTime(scheme.getScheduleStart());
		temp.add(Calendar.DAY_OF_YEAR, scheme.getWatchDays());
		Date watchDateEnd = temp.getTime();

		operationTaskList = new ArrayList<SOperationTask>();
		if (scheme.getScheduleOperationTasks() != null) {

			for (SOperationTask operationTask : scheme
					.getScheduleOperationTasks()) {
				if (log.isDebugEnabled()) {
					if (operationTask.getTaskUid().equals("3636935c")) {
						log.debug("aaaaaaaaa");
					}
				}
				if (operationTask.getDevice() != null
						&& !operationTask.getDevice().getDeviceUid().equals(
								"cooperation")
						&& operationTask.getDevice().getCriticalLevel() <= 2
						&& operationTask.getPlanStart() != null
						&& operationTask.getPlanStart().before(watchDateEnd)) {
					// 这一部分代码应该放在甘特图中去
					// todo,给甘特图充分的数据，然后由它自己负责显示
					// if(operationTask.isFinished())
					// {
					// operationTask.setTmpPercentCompleteDate(operationTask.getPlanFinish());
					// }
					// else
					// operationTask.setTmpPercentCompleteDate(scheme.getScheduleCurrentTime());

					// // 防止非里程碑
					// // 对准备工时的完成情况计算不准确
					// if (operationTask.getCompleteQty() > 0
					// && operationTask.getPlanFinish().after(
					// operationTask.getPlanStart())) {
					// double percentCompelete = scheduleOperationTaskManager
					// .calPercentComplete(operationTask);
					// Date tempDate = new Date();
					// tempDate.setTime((long) (operationTask.getPlanStart()
					// .getTime() + (operationTask.getPlanFinish()
					// .getTime() - operationTask.getPlanStart()
					// .getTime())
					// * percentCompelete));
					// operationTask.setTmpPercentCompleteDate(tempDate);
					// }
					operationTaskList.add(operationTask);
				}
			}

		}
		return operationTaskList;
	}

	/**
	 * get the operation task of the schedule scheme by taskuid
	 * 
	 * @param scheduleUid
	 * @param parentTaskUid
	 * @return
	 * @throws BaseDBException
	 */
	public List<SOperationTask> getOperationTaskList(String scheduleUid,
			String partTaskUid) throws Exception {
		// todo
		// 不结构化

		if (scheduleUid == null || scheduleUid.equals("")) {
//			scheduleUid = "schedule-" + SysUtil.getSessionDeptId();
			// parameters.put("scheduleUid", scheduleUid);
		}
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}

		List<SOperationTask> operationTaskList = new ArrayList<SOperationTask>();

		SPartTask partTask = scheme.getAllPartTaskMap().get(partTaskUid);
		if (partTask != null) {
			partTask.sortByOperationId();
			for (SOperationTask o : partTask.getOperationTaskList()) {
				if (!o.isFinished())
					operationTaskList.add(o);
			}
		}

		return operationTaskList;

	}

	/**
	 * 获取已经完工的工序任务 hba
	 * 
	 * @param scheduleUid
	 * @param partTaskUid
	 * @return
	 */
	public List<SOperationTask> getFinishedOperationTaskList(
			String scheduleUid, String partTaskUid) throws Exception {
		// todo
		// 不结构化

		if (scheduleUid == null || scheduleUid.equals("")) {
//			scheduleUid = "schedule-" + SysUtil.getSessionDeptId();
			// parameters.put("scheduleUid", scheduleUid);
		}
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}
		if (partTaskUid.equals("602a94e7-1570-4d9b-843a-fde8849901c2")) {
			log.info(partTaskUid);
		}
		List<SOperationTask> operationTaskList = new ArrayList<SOperationTask>();

		for (SOperationTask opTask : scheme.getAllOperationTaskMap().values()) {
			if (opTask.isFinished() && opTask.getParentTaskUid() != null
					&& opTask.getParentTaskUid().equals(partTaskUid)) {
				operationTaskList.add(opTask);
			}
		}
		if (operationTaskList.size() > 0) {
			Collections.sort(operationTaskList,
					new Comparator<SOperationTask>() {
						@Override
						public int compare(SOperationTask o1, SOperationTask o2) {
							if (o1.getActualFinish()
									.after(o2.getActualFinish())) {
								return 1;
							} else if (o1.getActualFinish().before(
									o2.getActualFinish())) {
								return -1;
							} else {
								if (o1.getOperationId() > o2.getOperationId()) {
									return 1;
								} else if (o1.getOperationId() < o2
										.getOperationId()) {
									return -1;
								} else {
									return 0;
								}
							}
							// TODO Auto-generated method stub
						}
					});
		}

		// SPartTask partTask = scheme.getAllPartTaskMap().get(partTaskUid);
		// if (partTask != null) {
		// partTask.sortByOperationId();
		// for (SOperationTask o : partTask.getOperationTaskList()) {
		// if (o.isFinished())
		// operationTaskList.add(o);
		// }
		// }

		return operationTaskList;

	}

	/**
	 * get the operation task of the schedule scheme by taskuid
	 * 
	 * @param scheduleUid
	 * @param parentTaskUid
	 * @return
	 * @throws BaseDBException
	 */
	public List<SOperationTask> getOperationTaskList(String scheduleUid,
			String partTaskUid, String outlineNumber) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}
		return scheduleOperationTaskManager
				.getOperationTaskListByOutlineNumber(scheme, partTaskUid,
						outlineNumber);

	}

	/**
	 * get the operation task of the schedule scheme by taskuid
	 * 
	 * @param scheduleUid
	 * @param parentTaskUid
	 * @return
	 * @throws BaseDBException
	 */
	public SOperationTask getOperationTask(String scheduleUid, String taskUid)
			throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}
		return scheme.getAllOperationTaskMap().get(taskUid);

	}

	/**
	 * change the operation task
	 * 
	 * @param scheduleUid
	 * @param operationTask
	 * @throws Exception
	 */
	public void updateOperationTask(String scheduleUid,
			SOperationTask operationTask, boolean modifyLink) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}

		scheduleOperationTaskManager.updateOperationTask(scheme, operationTask);

	}

	/**
	 * change the operation task
	 * 
	 * @param scheduleUid
	 * @param operationTask
	 * @throws Exception
	 */
	public void updateDeviceAssignedOperation(String scheduleUid,
			SOperationTask operationTask, boolean modifyLink) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}
		List<SOperationTask> opList = new ArrayList<SOperationTask>();
		opList.add(operationTask);
		scheduleOperationTaskManager.saveOperationTask(scheme, opList);
		int assnPriority = scheduleOperationTaskManager.calAssnPriority(
				operationTask, operationTask.getDeviceUid());
	}

	/**
	 * remove the operation task
	 * 
	 * @param scheduleUid
	 * @param operationTask
	 * @throws Exception
	 */
	public void removeOperationTask(String scheduleUid,
			SOperationTask operationTask) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}

		scheduleOperationTaskManager.removeOperationTask(scheme, operationTask
				.getTaskUid());

	}

	/**
	 * 
	 * @param scheduleUid
	 * @param taskUid
	 * @param deviceUid
	 * @param planStart
	 * @param planFinish
	 * @param locked
	 * @throws Exception
	 */
	public void updateOperationTask(String scheduleUid, String taskUid,
			String deviceUid, Date planStart, Date planFinish, int locked)
			throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}

		SOperationTask operationTask = scheme.getAllOperationTaskMap().get(
				taskUid);

		operationTask.setDeviceUid(deviceUid);
		SDevice device = getScheduleScheme(scheduleUid).getDeviceMap().get(
				deviceUid);
		if (device != null) {
			operationTask.setDevice(device);
			if (!device.getDeviceClass().equals(operationTask.getDeviceClass())) {
				operationTask.setDeviceClass(device.getDeviceClass());
				operationTask.setDeviceClassName(device.getDeviceClassName());
			}
		}
		operationTask.setPlanStart(planStart);
		operationTask.setPlanFinish(planFinish);
		operationTask.setLocked(locked);

	}

	/**
	 * save the change of a part task
	 * 
	 * @param scheduleUid
	 * @param partTask
	 * @throws Exception
	 */
	public void savePartTasks(String scheduleUid, List<SPartTask> partTaskList)
			throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}
		/**
		 * public List<SPartTask> getCombinedBatchs() 方法中 在由dorado
		 * 向其中传递数据时scheme为空，现在是在sheduleSchemeManager中强行注入了一个scheme
		 * 以后还是应该讲combinedBatchs实体化
		 */
		for (SPartTask partTask : partTaskList) {
			partTask.setScheme(scheme);
		}
		this.schedulePartTaskManager.savePartTask(scheme, partTaskList);
	}

	/**
	 * save the change of a part task
	 * 
	 * @param scheduleUid
	 * @param partTask
	 * @throws Exception
	 */
	public void updatePartTask(String scheduleUid, SPartTask partTask)
			throws Exception {
		String batchNum = partTask.getBatchNum();

		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		SPartTask originPartTask = scheme.getAllPartTaskMap().get(
				partTask.getTaskUid());
		originPartTask.setLateFinish(partTask.getLateFinish());
		// 临时
		originPartTask.setControlFinish(partTask.getLateFinish());

		this.schedulePartTaskManager.calcSlack(originPartTask);
		// BeanUtils.copyProperties(originPartTask, orig)

		// for (SPartTask partTask1 : scheme.getPartTaskList()) {
		// if (partTask1.getTaskUid().equals(partTask.getTaskUid())) {
		// partTask1.setControlFinish(partTask.getControlFinish());
		// partTask1.setLateFinish(partTask.getLateFinish());
		// this.schedulePartTaskManager.calcSlack(partTask1);
		// break;
		// }
		// }
	}

	/**
	 * calculate the plan finish time when plan start time or operation hour
	 * changed
	 * 
	 * @param scheduleUid
	 * @param taskUid
	 * @param planStart
	 * @param estiPreTime
	 * @param estiRunTime
	 * @param changeOperation
	 * @return
	 * @throws Exception
	 */
	public Date calcTaskPlanFinish(String scheduleUid, String taskUid,
			Date planStart, double estiPreTime, double estiRunTime,
			boolean changeOperation) throws Exception {
		Date planFinish = null;
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		SOperationTask aimOperationTask = scheme.getAllOperationTaskMap().get(
				taskUid);
		planFinish = scheduleOperationTaskManager.calcTaskPlanFinish(
				aimOperationTask, planStart, estiPreTime, estiRunTime,
				changeOperation);
		return planFinish;

	}

	/**
	 * add the selected part task to the schedule list
	 * 
	 * @param scheduleUid
	 * @param taskUidList
	 */
	public void addPartTasks(String scheduleUid, List<String> taskUidList) {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);

		for (String taskUid : taskUidList) {
			SPartTask partTask = scheme.getAllPartTaskMap().get(taskUid);
			try {
				this.schedulePartTaskManager.intoSchedule(partTask);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		// scheme.getRemainPartTaskList().removeAll(partTaskList);
	}

	/**
	 * remove the selected part task from the schedule list
	 * 
	 * @param scheduleUid
	 * @param taskUidList
	 */
	public void removePartTasks(String scheduleUid, List<String> taskUidList)
			throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		for (String taskUid : taskUidList) {
			SPartTask partTask = scheme.getAllPartTaskMap().get(taskUid);
			try {
				this.schedulePartTaskManager.outSchedule(partTask, true);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				// e.printStackTrace();
				throw e;
			}

		}

	}

	/**
	 * add the filtered part task to schedule list
	 * 
	 * @param parameters
	 */
	public void addAllTasks(String scheduleUid, Map parameters) {

		ScheduleScheme scheme = getScheduleScheme(scheduleUid);

		List<SPartTask> partTaskToBeAdded = this.schedulePartTaskManager
				.filter(scheme.getAllPartTaskMap().values(), parameters);
		try {
			this.schedulePartTaskManager.intoSchedule(partTaskToBeAdded);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * remove the filtered part task from the schedule list
	 * 
	 * @param parameters
	 */
	public void removeAllTasks(String scheduleUid, Map parameters) {

		ScheduleScheme scheme = getScheduleScheme(scheduleUid);

		List<SPartTask> partTaskToBeRemoved = this.schedulePartTaskManager
				.filter(scheme.getSchedulePartTasks(), parameters);

		try {
			this.schedulePartTaskManager.outSchedule(partTaskToBeRemoved, true);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * get the unscheduled tasks of the device class for the device gantt
	 * 
	 * @param scheduleUid
	 * @param deviceUid
	 * @param alarmLevel
	 * @param drawingId
	 * @param batchNum
	 * @param scope
	 * @param taskDistance
	 * @return
	 */
	public List<SOperationTask> getUnscheduledWCTaskList(String scheduleUid,
			String deviceUid, String alarmLevel, String drawingId,
			String batchNum, String scope, String taskDistance) {
		List<SOperationTask> operationTaskList = new ArrayList<SOperationTask>();
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);

		SDevice device = scheme.getDeviceMap().get(deviceUid);
		String deviceClass = device.getDeviceClass();
		int priority = Integer.valueOf(alarmLevel) + 1;

		for (SOperationTask operationTask : scheme.getScheduleOperationTasks()) {
			StringOper oper = new StringOper();
			if (!operationTask.getDeviceClass().equals(deviceClass))
				continue;
			if (oper.equals(drawingId, operationTask.getDrawingId())
					&& oper.equals(batchNum, operationTask.getBatchNum())
					&& operationTask.getPriority() <= priority) {
				if (scope != null && scope.equals("5")) {
					if (operationTask.getTaskDistance() < Integer
							.valueOf(taskDistance)) {
						operationTaskList.add(operationTask);
					}
				}

			}

		}
		this.scheduleOperationTaskManager
				.sortByPriorityTaskDistanceSlack(operationTaskList);
		return operationTaskList;
	}

	/**
	 * get the links of tasks for the gantt
	 * 
	 * @param scheduleUid
	 * @param partTaskUid
	 * @param partUid
	 * @return
	 */
	public List<SOperationLink> getLinkList(String scheduleUid,
			String partTaskUid, String partUid) {
		List<SOperationLink> links = new LinkedList<SOperationLink>();
		if (schemeMap.containsKey(scheduleUid)) {
			ScheduleScheme scheme = getScheduleScheme(scheduleUid);
			if (partTaskUid == null || partTaskUid.equals("")) {
				for (SPartTask partTask : scheme.getSchedulePartTasks()) {
					if (partTask.getPartUid().equals(partUid)) {
						for (SOperationTask operationTask : partTask
								.getOperationTaskList()) {
							links.addAll(operationTask.getPredLinkSet());
						}
					}
				}
			} else {
				SPartTask partTask = scheme.getAllPartTaskMap()
						.get(partTaskUid);
				if (partTask != null) {
					List<SOperationTask> ol = partTask.getOperationTaskList();
					if (ol != null && ol.size() > 0) {
						for (SOperationTask operationTask : ol) {
							links.addAll(operationTask.getPredLinkSet());
						}
					}
				}

			}
		}
		/**/
		return links;
	}

	/**
	 * add link between two operation tasks of different part task
	 * 
	 * @param scheduleUid
	 * @param operationLink
	 */
	public void addAssembleLink(String scheduleUid, SOperationLink operationLink) {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		String predTaskUid = operationLink.getPredecessorUid();
		String succTaskUid = operationLink.getSuccessorUid();

		SOperationLink link = new SOperationLink();
		link.setPredOperationTask(scheme.getAllOperationTaskMap().get(
				predTaskUid));
		link.setSuccOperationTask(scheme.getAllOperationTaskMap().get(
				succTaskUid));
		link.setDependType(2);

		try {
			this.scheduleLinkManager.addLink(link);
		} catch (Exception e) {

			// TODO Auto-generated catch block
			e.printStackTrace();

		}

	}

	public void deleteAssembleLink(String scheduleUid, String predTaskUid,
			String succTaskUid) {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);

		SOperationLink link = this.scheduleLinkManager.getLink(scheme,
				predTaskUid, succTaskUid);
		if (link != null)
			this.scheduleLinkManager.deleteLink(link);

		// List<SOperationLink> addtionalOperationLinks = schemeMap.get(
		// scheduleUid).getAdditionalOperationLinks();
		// for (SOperationLink operationLink : addtionalOperationLinks) {
		// if (operationLink.getPredecessorUid().equals(predTaskUid)
		// && operationLink.getSuccessorUid().equals(succTaskUid)) {
		// SOperationTask predOperationTask = operationLink
		// .getPredOperationTask();
		// SOperationTask succOperationTask = operationLink
		// .getSuccOperationTask();
		// // predOperationTask.getSuccLinkSet().contains(operationLink);
		// predOperationTask.getSuccLinkSet().remove(operationLink);
		// succOperationTask.getPredLinkSet().remove(operationLink);
		// // getScheduleScheme(scheduleUid).getAdditionalOperationLinks()
		// // .remove(operationLink);
		// break;
		// }
		// }
	}

	public List<SOperationLink> getAdditionalOperationLink(String scheduleUid) {
		// return null;
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		List<SOperationLink> opLinkList = new ArrayList<SOperationLink>();
		for (SOperationLink opLink : scheme.getAllOperationLinkMap().values()) {
			if (!opLink.getVirtualLink() && opLink.getDependType() != null
					&& opLink.getDependType() == 2) {
				opLinkList.add(opLink);
			}
		}
		// return getScheduleScheme(scheduleUid).getAdditionalOperationLinks();
		return opLinkList;
	}

	public List<SOperationLink> getPartOperationLink(String scheduleUid,
			String partTaskUid) throws Exception {
		ScheduleScheme scheme = null;
		if (schemeMap.containsKey(scheduleUid)) {
			scheme = getScheduleScheme(scheduleUid);
		} else {
			throw new Exception("找不到方案编号：" + scheduleUid);
		}

		return this.scheduleLinkManager.getPartOperationLink(scheme,
				partTaskUid);
	}

	public List<SOperationLink> getDeviceOperationLink(String scheduleUid,
			String deviceUid) throws Exception {
		ScheduleScheme scheme = null;
		if (schemeMap.containsKey(scheduleUid)) {
			scheme = getScheduleScheme(scheduleUid);
		} else {
			throw new Exception("找不到方案编号：" + scheduleUid);
		}

		return this.scheduleLinkManager.getDeviceOperationLink(scheme,
				deviceUid);
	}

	public SOperationTask groupTasks(String scheduleUid, String taskUids,
			String OperationIDDesc, Integer groupType) throws Exception {
		ScheduleScheme scheme = null;
		if (schemeMap.containsKey(scheduleUid)) {
			scheme = getScheduleScheme(scheduleUid);
		} else {
			throw new Exception("Error!");
		}

		String[] taskUid = taskUids.split(",");
		List<SPartTask> groupPartTasks = new ArrayList<SPartTask>();
		for (int i = 0; i < taskUid.length; i++) {
			groupPartTasks.add(scheme.getAllPartTaskMap().get(taskUid[i]));
		}
		return this.scheduleOperationTaskManager.groupTasks(groupPartTasks,
				OperationIDDesc, groupType);

	}

	public List<SOperationTask> getGroupTaskList(String scheduleUid)
			throws Exception {
		ScheduleScheme scheme = null;
		if (schemeMap.containsKey(scheduleUid)) {
			scheme = getScheduleScheme(scheduleUid);
		} else {
			throw new Exception("未找到对应部门的调度方案!");
		}
		return scheme.getGroupTaskList();
	}

	@Transactional
	public void exportScheduleScheme(String scheduleUid, String newScheduleUid)
			throws Exception {
		ScheduleScheme scheme = null;
		if (schemeMap.containsKey(scheduleUid)) {
			scheme = getScheduleScheme(scheduleUid);
		} else {
			throw new Exception("未找到对应部门的调度方案!");
		}
		// ScheduleScheme newScheme=new ScheduleScheme();
		// newScheme.setScheduleUid(IdentityGenerator.GetIdentityUUID());
		// newScheme.setScheduleName(scheduleName);
		// this.scheduleManager.add(newScheme);

		scheduleTaskDao.exportScheduleScheme(scheduleUid, newScheduleUid);
	}

	public void savePlan(String scheduleUid, String scheduleName,
			Date startDate, Date finishDate) throws Exception {
		ScheduleScheme scheme = null;
		if (schemeMap.containsKey(scheduleUid)) {
			scheme = getScheduleScheme(scheduleUid);
		} else {
			throw new Exception("未找到对应部门的调度方案!");
		}

		Calendar calendar = Calendar.getInstance();

		if (startDate == null) {
			calendar.setTime(new Date());
			calendar.add(Calendar.WEEK_OF_YEAR, 1);
			calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
			calendar.set(Calendar.HOUR_OF_DAY, 0);
			calendar.set(Calendar.MINUTE, 0);
			calendar.set(Calendar.SECOND, 0);
			calendar.set(Calendar.MILLISECOND, 0);
			startDate = calendar.getTime();
		} else {
			calendar.setTime(startDate);
			calendar.set(Calendar.HOUR_OF_DAY, 0);
			calendar.set(Calendar.MINUTE, 0);
			calendar.set(Calendar.SECOND, 0);
			calendar.set(Calendar.MILLISECOND, 0);
			startDate = calendar.getTime();
		}
		if (finishDate == null) {
			calendar.setTime(new Date());
			calendar.add(Calendar.WEEK_OF_YEAR, 2);
			calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
			calendar.set(Calendar.HOUR_OF_DAY, 23);
			calendar.set(Calendar.MINUTE, 59);
			calendar.set(Calendar.SECOND, 0);
			calendar.set(Calendar.MILLISECOND, 0);
			finishDate = calendar.getTime();
		} else {
			calendar.setTime(finishDate);
			// added by hba 用于保证能输出计划开始在结束日期当天的任务
			calendar.add(Calendar.DAY_OF_YEAR, 1);
			calendar.set(Calendar.HOUR_OF_DAY, 0);
			calendar.set(Calendar.MINUTE, 0);
			calendar.set(Calendar.SECOND, 0);
			calendar.set(Calendar.MILLISECOND, 0);
			finishDate = calendar.getTime();
		}
		scheduleTaskDao.savePlan(scheme, scheduleName, startDate, finishDate);
	}

	public void validateSchedule(String scheduleUid) throws Exception {
		ScheduleScheme scheme = null;
		if (schemeMap.containsKey(scheduleUid)) {
			scheme = getScheduleScheme(scheduleUid);
		} else {
			throw new Exception("Error!");
		}
		scheduleTaskDao.validateSchedule(scheme);
	}

	/**
	 * 
	 * @param scheduleUid
	 * @param drawingId
	 * @param batchNum
	 * @param lateFinish
	 * @param planGrade
	 * @param priority
	 * @return
	 */
	public List<SOperationTask> getCooperationTaskForAssign(String scheduleUid,
			String drawingId, String batchNum, Date lateFinish, int planGrade,
			int priority) {
		List<SOperationTask> cooperationTaskForAssign = new ArrayList<SOperationTask>();
		// if (schemeMap.containsKey(scheduleUid)) {
		// ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		// cooperationTaskForAssign = this.scheduleOperationTaskManager
		// .filter(scheme.getScheduleCooperationTaskList(), drawingId,
		// batchNum, lateFinish, planGrade, priority);
		// }
		return cooperationTaskForAssign;
	}

	/**
	 * 
	 * @param scheduleUid
	 * @param drawingId
	 * @param batchNum
	 * @param lateFinish
	 * @param planGrade
	 * @param priority
	 * @return
	 */
	public List<SOperationTask> getCooperateTaskNotAssign(String scheduleUid,
			String drawingId, String batchNum, Date lateFinish, int planGrade,
			int priority) {
		List<SOperationTask> cooperationTaskForAssign = new ArrayList<SOperationTask>();
		// if (schemeMap.containsKey(scheduleUid)) {
		// ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		// List<SOperationTask> remainCooperationTask = new
		// ArrayList<SOperationTask>();
		// remainCooperationTask.addAll(scheme.getCooperationTaskList());
		// remainCooperationTask.removeAll(scheme
		// .getScheduleCooperationTaskList());
		// cooperationTaskForAssign = this.scheduleOperationTaskManager
		// .filter(remainCooperationTask, drawingId, batchNum,
		// lateFinish, planGrade, priority);
		// }
		return cooperationTaskForAssign;
	}

	/**
	 * add chosen cooperate task to the scheduleList
	 * 
	 * @param scheduleUid
	 * @param taskUidList
	 */
	public void addCooperateTasks(String scheduleUid, List<String> taskUidList) {
		// ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		// if (scheme == null) {
		// return;
		// }
		// List<SOperationTask> cooperateTaskList = scheme
		// .getScheduleCooperationTaskList();
		//
		// for (String taskUid : taskUidList) {
		// for (SOperationTask cooperateTask : scheme.getCooperationTaskList())
		// {
		// if (cooperateTask.getTaskUid().equals(taskUid)) {
		// cooperateTaskList.add(cooperateTask);
		//
		// }
		// }
		// }
	}

	/**
	 * delete chosen cooperate task from the scheduleList
	 * 
	 * @param scheduleUid
	 * @param taskUidList
	 */
	public void removeCooperateTasks(String scheduleUid,
			List<String> taskUidList) {
		// ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		// if (scheme == null) {
		// return;
		// }
		//
		// List<SCoTask> scheduleCooperateTaskList = scheme
		// .getScheduleCooperationTaskList();
		// List<SOperationTask> cooperateTaskToBeDeleted = new
		// ArrayList<SOperationTask>();
		// for (String taskUid : taskUidList) {
		// for (SOperationTask coopTask : scheduleCooperateTaskList) {
		// if (coopTask.getTaskUid().equals(taskUid)) {
		// cooperateTaskToBeDeleted.add(coopTask);
		// }
		// }
		// }
		// for (SOperationTask coopTask : cooperateTaskToBeDeleted) {
		// coopTask.setPlanStart(null);
		// coopTask.setPlanFinish(null);
		// scheduleCooperateTaskList.remove(coopTask);
		// }
	}

	public void addAllCooperateTasks(String scheduleUid, String drawingId,
			String batchNum, Date lateFinish, int planGrade, int priority) {

		// ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		// if (scheme == null) {
		// return;
		// }
		// List<SOperationTask> remainCooperateTaskList = new
		// ArrayList<SOperationTask>();
		// List<SOperationTask> scheduleCooperateTaskList = scheme
		// .getScheduleCooperationTaskList();
		//
		// remainCooperateTaskList.addAll(scheme.getCooperationTaskList());
		// remainCooperateTaskList.removeAll(scheduleCooperateTaskList);
		//
		// List<SOperationTask> cooperateTaskToBeAdded =
		// this.scheduleOperationTaskManager
		// .filter(remainCooperateTaskList, drawingId, batchNum,
		// lateFinish, planGrade, priority);
		//
		// for (SOperationTask operationTask : cooperateTaskToBeAdded) {
		// scheduleCooperateTaskList.add(operationTask);
		// }

	}

	public void removeAllCooperateTask(String scheduleUid, String drawingId,
			String batchNum, Date lateFinish, int planGrade, int priority) {

		// ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		// if (scheme == null) {
		// return;
		// }
		// List<SOperationTask> cooperateTaskToBeRemoved =
		// this.scheduleOperationTaskManager
		// .filter(scheme.getScheduleCooperationTaskList(), drawingId,
		// batchNum, lateFinish, planGrade, priority);
		// for (SOperationTask operationTask : cooperateTaskToBeRemoved) {
		// operationTask.setPlanStart(null);
		// operationTask.setPlanFinish(null);
		// scheme.getScheduleCooperationTaskList().remove(operationTask);
		// }
	}

	public List<SOperationTask> getTimeStoneTask(String scheduleUid) {
		List<SOperationTask> timeStoneTaskList = new ArrayList<SOperationTask>();
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			return timeStoneTaskList;
		} else {
			for (SPartTask partTask : scheme.getSchedulePartTasks()) {
				if (partTask.getNextTimeStone() != null) {
					timeStoneTaskList.add(partTask.getNextTimeStone());
				}
			}
		}
		Collections.sort(timeStoneTaskList, new Comparator<Object>() {
			public int compare(Object o1, Object o2) {
				SOperationTask operationTask1 = (SOperationTask) o1;
				SOperationTask operationTask2 = (SOperationTask) o2;
				int i = 0;
				if (operationTask1.getWaitTime() < operationTask2.getWaitTime()) {
					i = 1;
				}
				return i;
			}
		});
		return timeStoneTaskList;
	}

	public List<SOperationTask> getDeviceOperations(String scheduleUid,
			String deviceUid, Date controlDate, Date planStart) {
		List<SOperationTask> deviceTaskList = new ArrayList<SOperationTask>();

		List<SOperationTask> deviceOperations = getDeviceTaskList(scheduleUid,
				deviceUid);
		for (SOperationTask operationTask : deviceOperations) {
			if (operationTask.getAssignState() == SOperationTask.ASSNSTATE_SUCCESS
					&& (operationTask.getPlanFinish().before(planStart) && operationTask
							.getPlanFinish().after(controlDate))
					|| (operationTask.getPlanStart().before(planStart) && operationTask
							.getPlanStart().after(controlDate))
					|| (operationTask.getPlanStart().before(controlDate) && operationTask
							.getPlanFinish().after(planStart))) {
				deviceTaskList.add(operationTask);
			}
		}
		return deviceOperations;
	}

	/**
	 * get the tasks assigned to the device
	 * 
	 * @param scheduleUid
	 * @param deviceUid
	 * @return
	 */
	public List<SOperationTask> getDeviceTaskList(String scheduleUid,
			String deviceUid) {
		List<SOperationTask> deviceTaskList = new ArrayList<SOperationTask>();
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme != null) {
			SDevice device = scheme.getDeviceMap().get(deviceUid);

			for (SOperationTask operationTask : scheme
					.getScheduleOperationTasks()) {
				if (operationTask.getDevice() == device) {
					deviceTaskList.add(operationTask);
				}
			}

		}

		Collections.sort(deviceTaskList, new Comparator<Object>() {
			public int compare(Object o1, Object o2) {
				SOperationTask opTask1 = (SOperationTask) o1;
				SOperationTask opTask2 = (SOperationTask) o2;
				int i = 0;
				if (opTask1.getPlanStart() != null
						&& opTask2.getPlanStart() != null) {
					if (opTask1.getPlanStart().after(opTask2.getPlanStart())) {
						i = 1;
					}

				}
				return i;
			}
		});

		return deviceTaskList;

	}

	/*
	 * 判断是否可以在该设备上加工
	 */
	private boolean canDo(String deviceUid, SOperationTask o) {

		if (o.getLocked() == 1 && o.getDeviceUid() != null
				&& !(o.getDeviceUid().equals(deviceUid)))
			return false;

		int assnPriority = scheduleOperationTaskManager.calAssnPriority(o,
				deviceUid);
		return assnPriority == 5 ? false : true;

	}

	/**
	 * get the tasks assigned to the device modified by hba for filtering by
	 * latefinish
	 * 
	 * @param scheduleUid
	 * @param deviceUid
	 * @return
	 */
	public List<SOperationTask> getTasksAssignedDevice(String scheduleUid,
			String deviceUid, String drawingId, Date lateFinish) {
		List<SOperationTask> deviceTaskList = new ArrayList<SOperationTask>();
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme != null && deviceUid != null) {
			if (lateFinish == null)
				lateFinish = scheme.getScheduleFinish();// 取最晚结束时间
			// todo
			// 应该改善速度
			// lqm
			for (SOperationTask operationTask : scheme
					.getScheduleOperationTasks()) {

				if (log.isDebugEnabled()) {
					if (operationTask.getTaskUid().equals(
							"d256227b-d460-44f6-9068-8ca9fe38cb4e")) {
						log.debug(operationTask.toFriendlyString());
					}

				}

				if (log.isDebugEnabled()) {
					if (operationTask.getTaskUid().equals(
							"72547c80-a68d-4063-83d7-ca8844de0e78")) {
						log.debug(operationTask.toFriendlyString());
					}

					if (operationTask.getTaskUid().equals(
							"6276498d-1512-40de-beff-91aceb39dee7")) {
						log.debug(operationTask.toFriendlyString());
					}
				}

				// 已将成组任务过滤掉
				if (operationTask.getAssignState() == SOperationTask.ASSNSTATE_SUCCESS
						&& operationTask.getDeviceUid() != null
						&& deviceUid.equals(operationTask.getDeviceUid())
						&& operationTask.getGroupTask() == null) {
					if (StringOper.equals(drawingId, operationTask
							.getDrawingId())) {
						// 有序列的无论怎样都显示
						if (operationTask.isDispatched()
								|| operationTask.isStarted()
								|| (operationTask.getDeviceSeq() != null && operationTask
										.getDeviceSeq() > 0)
								|| (operationTask.getPlanStart() != null && !operationTask
										.getControlFinish().after(lateFinish))) {
							deviceTaskList.add(operationTask);
						}
					}
				}
			}

			Collections.sort(deviceTaskList, new Comparator<Object>() {
				public int compare(Object o1, Object o2) {
					SOperationTask opTask1 = (SOperationTask) o1;
					SOperationTask opTask2 = (SOperationTask) o2;
					int i = 0;
					if (opTask1.getPlanStart() != null
							&& opTask2.getPlanStart() != null) {
						if (opTask1.getPlanStart()
								.after(opTask2.getPlanStart())) {
							i = 1;
						}
						if (opTask1.getPlanStart().before(
								opTask2.getPlanStart())) {
							return -1;
						}

					}
					return i;
				}
			});
		}
		return deviceTaskList;

	}

	/**
	 * get the tasks assigned to the device
	 * 
	 * @param scheduleUid
	 * @param deviceUid
	 * @return
	 */
	public List<SOperationTask> getTasksNotAssignedToDevice(String scheduleUid,
			String deviceUid, Date arriveDate, Integer taskDistance,
			String drawingId) {

		List<SOperationTask> deviceTaskList = new ArrayList<SOperationTask>();
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null || deviceUid == null) {
			return deviceTaskList;
		}
		// Date arriveDate1 = arriveDate;
		// Date arriveDate2 = arriveDate;
		// if (arriveDate != null) {
		// Calendar calendar = Calendar.getInstance();
		// calendar.setTime(arriveDate);
		// calendar.set(Calendar.HOUR_OF_DAY, 23);
		// calendar.set(Calendar.MINUTE, 59);
		// calendar.set(Calendar.SECOND, 59);
		// arriveDate1 = calendar.getTime();
		// calendar.set(Calendar.HOUR_OF_DAY, 0);
		// calendar.set(Calendar.MINUTE, 0);
		// calendar.set(Calendar.SECOND, 0);
		// calendar.set(Calendar.MILLISECOND, 0);
		// arriveDate2 = calendar.getTime();
		// }
		if (taskDistance == null) {
			taskDistance = 500;
		}

		SDevice device = scheme.getDeviceMap().get(deviceUid);
		if (device == null) {
			return deviceTaskList;
		}
		// 忽略其工作中心
		// String deviceClass = device.getDeviceClass();
		//		
		// operationTask.getDeviceClass() != null
		// && operationTask.getDeviceClass().equals(deviceClass)
		// &&
		for (SOperationTask operationTask : scheme.getScheduleOperationTasks()) {
			if (operationTask.getTaskDistance() < taskDistance
					&& StringOper.equals(drawingId, operationTask
							.getDrawingId())) {

				if (!operationTask.isFinished()
						&& !deviceUid.equals(operationTask.getDeviceUid())
						&& canDo(deviceUid, operationTask)
						&& operationTask.getGroupTask() == null)
					deviceTaskList.add(operationTask);
				// if (showAll) {
				// deviceTaskList.add(operationTask);
				// } else {
				// if (operationTask.getDevice() == null) {
				// deviceTaskList.add(operationTask);
				// }
				// }
				// if (arriveDate == null) {
				// }
				// else {
				// if (operationTask.getControlStart().after(arriveDate2)
				// && operationTask.getControlStart().before(
				// arriveDate1)) {
				// if (showAll) {
				// deviceTaskList.add(operationTask);
				// } else {
				// if (operationTask.getDevice() == null) {
				// deviceTaskList.add(operationTask);
				// }
				// }
				// }
				// }
			}

			// 按照优先级和松弛度进行排序
			Collections.sort(deviceTaskList, new Comparator<Object>() {

				public int compare(Object o1, Object o2) {
					SOperationTask operTask1 = (SOperationTask) o1;
					SOperationTask operTask2 = (SOperationTask) o2;
					int i = 0;
					if (operTask1.getPriority() > operTask2.getPriority()
							|| operTask1.getPriority() == operTask2
									.getPriority()
							&& operTask1.getSlackFactor() > operTask2
									.getSlackFactor()) {
						i = 1;
					}
					return i;
				}

			});
		}
		return deviceTaskList;
	}

	/**
	 * get the tasks assigned to the device
	 * 
	 * @param scheduleUid
	 * @param deviceUid
	 * @return
	 */
	public List<SOperationTask> getTasksOfDeviceClass(String scheduleUid,
			String deviceUid, Date arriveDate, Integer taskDistance,
			Boolean showAll) {

		List<SOperationTask> deviceTaskList = new ArrayList<SOperationTask>();
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			return deviceTaskList;
		}
		Date arriveDate1 = arriveDate;
		Date arriveDate2 = arriveDate;
		if (arriveDate != null) {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(arriveDate);
			calendar.set(Calendar.HOUR_OF_DAY, 23);
			calendar.set(Calendar.MINUTE, 59);
			calendar.set(Calendar.SECOND, 59);
			arriveDate1 = calendar.getTime();
			calendar.set(Calendar.HOUR_OF_DAY, 0);
			calendar.set(Calendar.MINUTE, 0);
			calendar.set(Calendar.SECOND, 0);
			calendar.set(Calendar.MILLISECOND, 0);
			arriveDate2 = calendar.getTime();
		}
		if (taskDistance == null) {
			taskDistance = 100;
		}
		if (showAll == null) {
			showAll = false;
		}
		SDevice device = scheme.getDeviceMap().get(deviceUid);
		if (device == null) {
			return deviceTaskList;
		}
		String deviceClass = device.getDeviceClass();

		for (SOperationTask operationTask : scheme.getScheduleOperationTasks()) {

			if (operationTask.getDeviceClass() != null
					&& operationTask.getDeviceClass().equals(deviceClass)
					&& operationTask.getDevice() != device
					&& operationTask.getTaskDistance() < taskDistance) {

				if (arriveDate == null) {
					if (showAll) {
						deviceTaskList.add(operationTask);
					} else {
						if (operationTask.getDevice() == null) {
							deviceTaskList.add(operationTask);
						}
					}
				} else {
					if (operationTask.getControlEarlyStart().after(arriveDate2)
							&& operationTask.getControlEarlyStart().before(
									arriveDate1)) {
						if (showAll) {
							deviceTaskList.add(operationTask);
						} else {
							if (operationTask.getDevice() == null) {
								deviceTaskList.add(operationTask);
							}
						}
					}
				}
			}

		}

		Collections.sort(deviceTaskList, new Comparator<Object>() {

			public int compare(Object o1, Object o2) {
				SOperationTask opTask1 = (SOperationTask) o1;
				SOperationTask opTask2 = (SOperationTask) o2;
				int i = 0;
				if (opTask1.getPriority() >= opTask2.getPriority()) {
					i = 1;
				}
				return i;
			}

		});
		return deviceTaskList;
	}

	/**
	 * 获取比CriticalLevel更重要的设备列表，更优先
	 * 
	 * @param scheduleUid
	 * @return
	 * @throws Exception
	 */
	public List<SDevice> getDeviceList(String scheduleUid, int CriticalLevel)
			throws Exception {
		List<SDevice> deviceList = new ArrayList<SDevice>();
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			return null;
		}
		if (scheme.getDeviceMap() != null) {
			for (SDevice device : scheme.getDeviceMap().values()) {
				if (!device.getVirtual()
						&& device.getCriticalLevel() <= CriticalLevel) {
					deviceList.add(device);
				}
			}
		} else {
//			deviceList = deviceDao.getDeviceList(scheme.getDeptUid());
		}
		Collections.sort(deviceList, new Comparator<Object>() {
			public int compare(Object o1, Object o2) {
				SDevice d1 = (SDevice) o1;
				SDevice d2 = (SDevice) o2;
				int i = -1;
				// if (d1.getCriticalLevel() > d2.getCriticalLevel())
				// i = 1;
				// else if (d1.getCriticalLevel() == d2.getCriticalLevel()) {
				if (d1.getDeviceClassName().compareTo(d2.getDeviceClassName()) > 0) {
					i = 1;
				} else if (d1.getDeviceClassName().compareTo(
						d2.getDeviceClassName()) == 0) {
					if (d1.getDeviceName().compareTo(d2.getDeviceName()) > 0) {
						i = 1;
					}
					// }
				}
				return i;
			}
		});
		return deviceList;
	}

	/**
	 * get the device list
	 * 
	 * @param scheduleUid
	 * @return
	 * @throws Exception
	 */
	public List<SDevice> getDeviceList(String scheduleUid) throws Exception {
		List<SDevice> deviceList = new ArrayList<SDevice>();
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			return null;
		}
		if (scheme.getDeviceMap() != null) {
			for (SDevice device : scheme.getDeviceMap().values()) {
				if (!device.getVirtual()) {
					deviceList.add(device);
				}
			}
		} else {
//			deviceList = deviceDao.getDeviceList(scheme.getDeptUid());
		}
		/*
		 * Collections.sort(deviceList, new Comparator<Object>() { public int
		 * compare(Object o1, Object o2) { Device d1 = (Device) o1; Device d2 =
		 * (Device) o2; int i = 0; if
		 * (d1.getDeviceClass().compareTo(d2.getDeviceClass()) > 0) { i = 1; }
		 * return i; } });
		 */
		Collections.sort(deviceList, new Comparator<Object>() {
			public int compare(Object o1, Object o2) {
				SDevice d1 = (SDevice) o1;
				SDevice d2 = (SDevice) o2;
				int i = -1;
				if (d1.getDeviceClassName().compareTo(d2.getDeviceClassName()) > 0)
					i = 1;
				else if (d1.getDeviceClassName().compareTo(
						d2.getDeviceClassName()) == 0) {
					if (d1.getDeviceName().compareTo(d2.getDeviceName()) > 0) {
						i = 1;
					}
				}
				return i;
			}
		});
		return deviceList;
	}

	/**
	 * 按照树节点获取设备列表hba
	 * 当resUid为空时则获取部门下的所有设备，当resUid为工作中心编号时，则获取中心下的设备，否则获取编号为resUid的设备
	 * 
	 * @param scheduleUid
	 * @param resUid
	 * @return
	 * @throws Exception
	 */
	public List<SDevice> getDeviceList(String scheduleUid, String resUid)
			throws Exception {

		// TODO Auto-generated method stub
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			return null;
		}
		List<SDevice> deviceList = new ArrayList<SDevice>();
		if (resUid == null || resUid.equals("")
				|| resUid.equals(scheme.getDeptUid())) {
			deviceList = this.getDeviceList(scheduleUid);
		} else {
			// 工作中心编号
			if (scheme.getWorkCenterMap().get(resUid) != null) {
				for (SDevice device : scheme.getDeviceMap().values()) {
					if (device.getDeviceClass() != null
							&& device.getDeviceClass().equals(resUid)) {
						deviceList.add(device);
					}
				}
			} else {
				if (scheme.getDeviceMap().containsKey(resUid)) {
					deviceList.add(scheme.getDeviceMap().get(resUid));
				}
			}
		}
		Collections.sort(deviceList, new Comparator<SDevice>() {
			@Override
			public int compare(SDevice o1, SDevice o2) {
				// TODO Auto-generated method stub
				return o1.getDeviceUid().compareTo(o2.getDeviceUid()) * (-1);
			}
		});
		return deviceList;
	}

	/**
	 * get the device class list for the gantt graph
	 * 
	 * @param scheduleUid
	 * @return
	 * @throws Exception
	 */
	public List<SDevice> getDeviceClassList(String scheduleUid)
			throws Exception {
		List<SDevice> deviceTypeList = new ArrayList<SDevice>();
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			// throw new Exception("请先打开调度方案!");
			return null;
		}
		// todo
		// 应该有工作中心这一层
		if (scheme.getDeviceMap() != null) {

			Map<String, SDevice> deviceClassMap = new HashMap<String, SDevice>();
			for (SDevice device : scheme.getDeviceMap().values()) {
				if (!device.getVirtual()
						&& !deviceClassMap.containsKey(device.getDeviceClass())
						&& !device.getDeviceClass().equals("cooperationCenter")) {
					SDevice temp = new SDevice();
					temp.setDeviceClass(device.getDeviceClass());
					temp.setDeviceClassName(device.getDeviceClassName());
					temp.setDeviceName(device.getDeviceClassName());
					deviceClassMap.put(device.getDeviceClass(), temp);
				}
			}
			for (SDevice device : deviceClassMap.values()) {
				deviceTypeList.add(device);
			}

		} else {
//			deviceTypeList = deviceDao.getDeviceClassList(scheme.getDeptUid());
		}

		return deviceTypeList;
	}

	public List<CalendarData> getDeviceException(String scheduleUid,
			String deviceUid) throws Exception {
		if (scheduleUid == null)
			throw new Exception("调度方案编号不能为空!");
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}

		SDevice device = scheme.getDeviceMap().get(deviceUid);
		if (device != null) {
			return scheduledeviceManager.getDeviceException(device, scheme);
		}
		return null;

	}

	/**
	 * get the device list of the task to choose from
	 * 
	 * @param scheduleUid
	 * @param taskUid
	 * @return
	 * @throws Exception
	 */
	public List<SDevice> getOperationDeviceList(String scheduleUid,
			String taskUid) throws Exception {
		List<SDevice> deviceList = new ArrayList<SDevice>();
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}
		/*
		 * List<SPartTask> partTaskList = scheme.getPartTaskList();
		 * partTaskList.addAll(scheme.getRemainPartTaskList());
		 */
		SOperationTask operTask = scheme.getAllOperationTaskMap().get(taskUid);
		for (ResourceConstraint rc : operTask.getAlterResourceMap().values()) {
			deviceList.add(rc.getDevice());
		}

		return deviceList;
	}

	/**
	 * calculate the load of the device classes and return
	 * 
	 * @param scheduleUid
	 * @return
	 * @throws Exception
	 */
	public List<SDevice> getDeviceClassUtilList(String scheduleUid)
			throws Exception {

		List<SDevice> deviceTypeList = getDeviceClassList(scheduleUid);
		List<SDevice> deviceList = getDeviceList(scheduleUid);
		for (SDevice deviceClass : deviceTypeList) {
			int count = 0;
			double loadRation = 0;
			double utilRation = 0;
			for (SDevice device : deviceList) {
				if (device.getDeviceClass()
						.equals(deviceClass.getDeviceClass())) {
					count++;
					loadRation += device.getAverageLoadRation();
					utilRation += device.getAverageUtilRation();
				}
			}
			if (count != 0) {
				deviceClass.setAverageLoadRation(loadRation / count);
				deviceClass.setAverageUtilRation(utilRation / count);
			} else {
				deviceClass.setAverageLoadRation(0);
				deviceClass.setAverageUtilRation(0);
			}
		}
		Collections.sort(deviceTypeList, new Comparator<Object>() {
			public int compare(Object o1, Object o2) {
				SDevice device1 = (SDevice) o1;
				SDevice device2 = (SDevice) o2;
				int i = 0;
				if (device1.getAverageLoadRation() < device2
						.getAverageLoadRation()) {
					i = 1;
				}
				return i;
			}
		});
		return deviceTypeList;

	}

	/**
	 * get the load of the devices of the device class
	 * 
	 * @param scheduleUid
	 * @param deviceClass
	 * @return
	 * @throws Exception
	 */
	public List<SDevice> getDeviceUtilList(String scheduleUid,
			String deviceClass) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}
		List<SDevice> deviceList = new ArrayList<SDevice>();

		try {
			for (SDevice device : scheme.getDeviceMap().values()) {
				if (device.getDeviceClass() != null
						&& device.getDeviceClass().equals(deviceClass)) {
					deviceList.add(device);
				}
			}
		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return deviceList;

	}

	/**
	 * return the device
	 * 
	 * @param scheduleUid
	 * @param deviceUid
	 * @return
	 * @throws Exception
	 */
	public SDevice getDevice(String scheduleUid, String deviceUid)
			throws Exception {
		List<SDevice> deviceList = getDeviceList(scheduleUid);
		if (deviceList != null && deviceList.size() > 0) {
			for (SDevice device : deviceList) {
				if (device.getDeviceUid().equals(deviceUid)) {
					return device;
				}
			}
		}
		return null;
	}

	/**
	 * change a different device for the task
	 * 
	 * @param scheduleUid
	 * @param taskUid
	 * @param deviceUid
	 * @param priority
	 */
	public void changeDevice(String scheduleUid, String taskUid,
			String deviceUid) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		SDevice device = scheme.getDeviceMap().get(deviceUid);
		SOperationTask operTask = scheme.getAllOperationTaskMap().get(taskUid);

		this.scheduleOperationTaskManager.changeDevice(operTask, device);

	}

	/**
	 * get the tasks that wait longer than the wainning days
	 * 
	 * @param scheduleUid
	 * @return
	 * @throws Exception
	 */
	public List<SOperationTask> getWaitTaskList(String scheduleUid,
			String parentTaskUid) throws Exception {
		List<SOperationTask> waitTaskList = new ArrayList<SOperationTask>();
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}
		// int warningWaitDays = scheme.getWarningWaitDays()==null?2:
		// scheme.getWarningWaitDays();
		SPartTask partTask = scheme.getAllPartTaskMap().get(parentTaskUid);
		if (partTask != null) {
			for (SOperationTask operationTask : partTask.getOperationTaskList()) {
				// getwaittime缺省单位为天

				SDevice device = operationTask.getDevice();
				if (device != null
						&& (device instanceof McDevice || device instanceof UcDevice))
					continue;

				if (log.isDebugEnabled()) {
					if (operationTask.getTaskUid().equals(
							"fd492d16-97b1-402e-8f3e-b0c52c69d605")) {
						log.debug("aaaaaaaaaaaaaaaa");
					}
				}

				if (operationTask.getWaitTime() > 0.1) {
					operationTask
							.setAssnPriority(this.scheduleOperationTaskManager
									.calAssnPriority(operationTask,
											operationTask.getDeviceUid()));
					waitTaskList.add(operationTask);
				}
			}
		}
		// 同一零件不排序

		// Collections.sort(waitTaskList, new Comparator<Object>() {
		// public int compare(Object o1, Object o2) {
		// SOperationTask operTask1 = (SOperationTask) o1;
		// SOperationTask operTask2 = (SOperationTask) o2;
		// int i = -1;
		// if (operTask1.getWaitTime() < operTask2.getWaitTime()) {
		// i = 1;
		// }
		// return i;
		// }
		// });
		return waitTaskList;
	}

	/**
	 * refresh the color of the part tasks
	 * 
	 * @param scheduleUid
	 * @throws Exception
	 */
	/**
	 * @author SnowBear
	 * @param scheduleUid
	 * @throws Exception
	 */
	public void refreshColor(String scheduleUid) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}
		this.scheduleManager.refreshSlackAndColor(scheme);

	}

	/**
	 * remove all the tasks assigned to the devices not for sure on the device
	 * gantt
	 * 
	 * @param scheduleUid
	 * @throws Exception
	 */
	public void removePreAssnTask(String scheduleUid) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}
		for (SOperationTask operTask : scheme.getScheduleOperationTasks()) {
			if (operTask.getTaskState() == 205 && operTask.getLocked() == 0) {
				operTask.setDevice(null);
			}

		}

	}

	/**
	 * remove other schedules to make sure only one schedule for a dept is
	 * effective
	 * 
	 * @param scheduleUid
	 * @throws Exception
	 */
	public void removeOtherSchedule(String scheduleUid) throws Exception {
		// Set<Entry<String, ScheduleScheme>> entries = schemeMap.entrySet();
		// Iterator<Entry<String, ScheduleScheme>> itor = entries.iterator();
		// List<String> scheduleUidList = new ArrayList<String>();
		// ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		// scheme.setEffective(true);
		// String deptId = scheme.getDeptUid();
		// while (itor.hasNext()) {
		// Entry<String, ScheduleScheme> k = itor.next();
		// if (!k.getKey().equals(scheduleUid)
		// && k.getValue().getDeptUid().equals(deptId)) {
		// scheduleUidList.add(k.getKey());
		// }
		// }
		// for (String string : scheduleUidList) {
		// schemeMap.remove(string);
		// }

	}

	/**
	 * delete a schedule
	 * 
	 * @param scheduleUid
	 * @throws Exception
	 */
	public void deleteScheme(String scheduleUid) throws Exception {
		if (schemeMap.containsKey(scheduleUid)) {
			this.scheduleManager.delete(getScheduleScheme(scheduleUid));
			schemeMap.remove(scheduleUid);
		} else {
			// 直接删除
			//by lcs 原来方法
			//this.scheduleManager.deleteById(scheduleUid);
			this.scheduleManager.delete(scheduleSchemeDao.getById(scheduleUid));
		}
	}

	public void removeScheme(String scheduleUid) throws Exception {
		if (schemeMap.containsKey(scheduleUid)) {
			SchemeActiveControl sac = schemeMap.get(scheduleUid);
			if (sac.getScheme() != null)
				sac.getScheme().destroy();
			sac = null;
			schemeMap.remove(scheduleUid);

		}
	}

	public void changeDeviceInfo(String scheduleUid, SDevice device)
			throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		// if (scheme != null) {
		// Map<String, Device> deviceMap = scheme.getDeviceMap();
		// Device temp = deviceMap.get(device.getDeviceUid());
		// if (temp != null) {
		// temp.setResCapacity(device.getResCapacity());
		// if (!(device.getCalendarUid().equals(temp.getCalendarUid()))) {
		// if (scheme.getCalendarMap().containsKey(
		// device.getCalendarUid())) {
		// temp.setCalendarUid(device.getCalendarUid());
		// temp.setCalendar(scheme.getCalendarMap().get(
		// device.getCalendarUid()));
		// } else {
		// SCalendar scalendar = deviceDao.initCalendar(device
		// .getCalendarUid(), scheme.getScheduleStart(),
		// scheme.getScheduleFinish());
		// scheme.getCalendarMap().put(device.getCalendarUid(),
		// scalendar);
		// device.setCalendar(scalendar);
		// }
		// }
		// if (temp.getCriticalLevel() != device.getCriticalLevel()) {
		// int criticalLevel = temp.getCriticalLevel();
		// temp.setCriticalLevel(device.getCriticalLevel());
		// if (device.getCriticalLevel() == 1) {
		// temp.setDeviceName(temp.getDeviceName() + "*");
		// }
		// if (criticalLevel == 1) {
		// int index = temp.getDeviceName().indexOf("*");
		// if (index != -1) {
		// temp.setDeviceName(temp.getDeviceName().substring(
		// 0, index));
		// }
		// }
		// }
		// this.deviceDao.updateDevice(temp);
		// }
		// }
	}

	public void setPS(String scheduleUid, String parentTaskUid,
			float startOperation, float endOperation, int transferCount) {
		// ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		// if (scheme != null) {
		// for (SPartTask partTask : scheme.getPartTaskList()) {
		// if (partTask.getTaskUid().equals(parentTaskUid)) {
		// this.schedulePartTaskManager.setPS(partTask,
		// startOperation, endOperation, transferCount);
		// this.scheduleTaskDao.saveConstraint(scheduleUid, partTask,
		// 3, "");
		// break;
		// }
		//
		// }
		// }
	}

	public void compressOperationTaskByPartTask(String scheduleUid,
			String parentTaskUid) {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme != null) {
			SPartTask partTask = scheme.getAllPartTaskMap().get(parentTaskUid);

			this.schedulePartTaskManager
					.compressOperationTaskByPartTask(partTask);

		}
	}

	/*
	 * // public List<SPartTask> getPSTasks(String scheduleUid) { ////
	 * ScheduleScheme scheme = getScheduleScheme(scheduleUid); //// List<SPartTask>
	 * pSTaskList = new ArrayList<SPartTask>(); //// if (scheme != null) { ////
	 * for (SPartTask partTask : scheme.getAllPartTaskMap().values()) { //// if
	 * (partTask.isPS() == true) { //// pSTaskList.add(partTask); //// } //// }
	 * //// } //// return pSTaskList; // }
	 */
	@Deprecated
	public void splitBatch(String scheduleUid, String parentTaskUid,
			List<SOperationTask> splitedBatch) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		SPartTask partTask = scheme.getAllPartTaskMap().get(parentTaskUid);
		this.schedulePartTaskManager.splitBatch(partTask, splitedBatch);
	}

	public List<SPartTask> getOriginalBatchBeforeSplit(String scheduleUid) {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme != null) {
			return scheme.getSplitedPartTaskList();
		}
		return null;
	}

	public List<SPartTask> getSplitBatch(String scheduleUid, String taskUid) {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);

		if (scheme != null) {
			for (SPartTask partTask : scheme.getSplitedPartTaskList()) {
				if (partTask.getTaskUid().equals(taskUid)) {
					return partTask.getSplitedBatchs();
				}
			}
		}
		return null;
	}

	public void combineBatch(String scheduleUid, String taskUids, int mode)
			throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme != null) {
			String[] uids = taskUids.split(",");
			List<SPartTask> combineBatchList = new ArrayList<SPartTask>();
			for (String taskUid : uids) {
				SPartTask partTask = scheme.getAllPartTaskMap().get(taskUid);
				if (partTask == null) {
					// throw new Exception("找不到任务号对应的任务" + taskUid);
				} else
					combineBatchList.add(partTask);
			}

			// 这些批次可能对应不同的订单 (hba
			DemandSTaskLinkDao demandSTaskLinkDao = SpringUtils
					.getBean("demandSTaskLinkDao");
			DemandSTaskLinkManager demandSTaskLinkManager = SpringUtils
					.getBean("demandSTaskLinkManager");
			List<DemandSTaskLink> comDemandsTaskLink = new ArrayList<DemandSTaskLink>();
			for (SPartTask partTask : combineBatchList) {
				List<DemandSTaskLink> demandTaskLinks = demandSTaskLinkDao
						.getEffectiveLinksByTask(scheduleUid, partTask
								.getTaskUid());
				comDemandsTaskLink.addAll(demandTaskLinks);
			}// )

			// 写日志
			String batchNum = "";
			int planQty = 0;
			for (SPartTask partTask : combineBatchList) {
				batchNum += partTask.getBatchNum() + ",";
				planQty += partTask.getPlanQty();
			}
			batchNum = batchNum.substring(0, batchNum.length() - 1);
			SPartTask newTask = combineBatchList.get(0);

			SPartTask newPartTask = this.schedulePartTaskManager.combineBatch(
					combineBatchList, mode);
			// (hba
			newPartTask.setDemandLinkQty(0.0);
			for (DemandSTaskLink demandSTaskLink : comDemandsTaskLink) {
				DemandSTaskLink newDemandSTaskLink = new DemandSTaskLink();
				newDemandSTaskLink.setDemandUid(demandSTaskLink.getDemandUid());
				newDemandSTaskLink.setPartTaskUid(newPartTask.getTaskUid());
				newDemandSTaskLink.setIsInEffect(1);
				newDemandSTaskLink.setLinkQty(demandSTaskLink.getLinkQty());
				newDemandSTaskLink.setLockLevel(0);
				newDemandSTaskLink.setDependType("1");
				newDemandSTaskLink.setPartTask(newPartTask);
				newDemandSTaskLink.setScheduleUid(scheduleUid);
				// demand.setArrangeQty(demand.getDueQty().floatValue());
				newPartTask.setDemandLinkQty(newPartTask.getDemandLinkQty()
						+ demandSTaskLink.getLinkQty());
				demandSTaskLinkManager.saveOrUpdateLink(newDemandSTaskLink);
			}

			// 这个地方不能简单的删除，因为在取消合批时无法恢复之间的关联关系,在上面设置链接无效
			// demandSTaskLinkManager.delete(comDemandsTaskLink);
			// )
			/*
			 * Element taskElement = new Element("PARTTASK_COMBINEBATCH");
			 * taskElement.setAttribute("taskUid", newTask.getTaskUid());
			 * taskElement.setAttribute("batchNum", batchNum);
			 * taskElement.setAttribute("partUid", newTask.getPartUid());
			 * taskElement.setAttribute("drawingId", newTask.getDrawingId());
			 * taskElement.setAttribute("partName", newTask.getPartName());
			 * taskElement.setAttribute("planQty", String.valueOf(planQty)); for
			 * (SPartTask partTask : combineBatchList) { Element
			 * combineTaskElement = new Element("combineTask");
			 * combineTaskElement.setAttribute("batchNum", partTask
			 * .getBatchNum()); combineTaskElement.setAttribute("planQty",
			 * String .valueOf(partTask.getPlanQty()));
			 * combineTaskElement.setAttribute("taskUid", partTask
			 * .getTaskUid()); taskElement.addContent(combineTaskElement); }
			 * this.scheduleOperationRecordManager.writeCombineBatchLog(scheme,
			 * combineBatchList); this.scheduleEventManager.writeOperLog(scheme,
			 * ScheduleEvent.EVENTTYPE_PARTTASK_COMBINEBATCH, taskElement);
			 */
		}
	}

	public void removeBatchFromCombinedBatch(String scheduleUid,
			String combinedTaskUid, String removedBatchNums) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);

		if (scheme != null) {

			schedulePartTaskManager.removeBatchFromCombinedBatch(scheme,
					combinedTaskUid, removedBatchNums);

		}

	}

	public List<SPartTask> getcombinedBatch(String scheduleUid, String drawingId) {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		List<SPartTask> rootBatchList = new ArrayList<SPartTask>();
		if (scheme != null) {
			if (drawingId.equals("")) {
				for (SPartTask partTask : scheme.getCombineBatchList()) {
					if (partTask.getTaskScheduleType() == 1) {
						rootBatchList.add(partTask);
					}
				}
			} else {
				for (SPartTask partTask : scheme.getCombineBatchList()) {
					if (partTask.getTaskScheduleType() == 1
							&& partTask.getDrawingId().equals(drawingId)) {
						rootBatchList.add(partTask);
					}
				}
			}

		}

		return rootBatchList;
	}

	public List<SPartTask> getOriginalBatchBeforeCombine(String scheduleUid,
			String taskUid) {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme != null) {
			SPartTask partTask = scheme.getAllPartTaskMap().get(taskUid);
			return partTask.getCombinedBatchs();

		}
		return null;
	}

	public void cancelPS(String scheduleUid, String taskUid) {
		// ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		// if (scheme != null) {
		// for (SPartTask partTask : scheme.getPartTaskList()) {
		// if (partTask.getTaskUid().equals(taskUid)) {
		// partTask.setPS(false);
		// for (SOperationTask operationTask : partTask
		// .getOperationTaskList()) {
		// operationTask.setPSOperation(false);
		// }
		// this.scheduleTaskDao.deleteConstraint(scheduleUid,
		// partTask, 3);
		// break;
		// }
		// }
		// }
	}

	public void cancelSplitBatch(String scheduleUid, String taskUid) {
		// ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		// if (scheme != null) {
		// for (SPartTask partTask : scheme.getSplitedPartTaskList()) {
		// if (partTask.getTaskUid().equals(taskUid)) {
		// for (SPartTask root : scheme.getSplitedPartTaskList()) {
		// if (root.getSplitedBatchs().containsAll(
		// partTask.getSplitedBatchs())
		// && root != partTask) {
		// root.getSplitedBatchs().add(partTask);
		// root.getSplitedBatchs().removeAll(
		// partTask.getSplitedBatchs());
		// }
		// }
		// for (SPartTask root : scheme.getSplitedPartTaskList()) {
		// if (partTask.getSplitedBatchs().containsAll(
		// root.getSplitedBatchs())
		// && root != partTask) {
		// scheme.getSplitedPartTaskList().remove(root);
		// break;
		// }
		// }
		// scheme.getPartTaskList().add(partTask);
		// scheme.getAllPartTaskMap().put(partTask.getTaskUid(), partTask);
		// scheme.getPartTaskList().removeAll(
		// partTask.getSplitedBatchs());
		// scheme.getAllPartTaskList().removeAll(
		// partTask.getSplitedBatchs());
		// scheme.getSplitedPartTaskList().remove(partTask);
		// for (SPartTask partTask2 : partTask.getSplitedBatchs()) {
		// this.scheduleTaskDao.deleteConstraint(scheduleUid,
		// partTask2, 2);
		// }
		// break;
		// }
		// }
		// }
	}

	public void cancelCombineBatch(String scheduleUid, String taskUid)
			throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null)
			return;
		SPartTask partTask = scheme.getAllPartTaskMap().get(taskUid);
		schedulePartTaskManager.cancelCombineBatch(scheme, taskUid);
		// 写日志

		List<SPartTask> combinedBatchs = partTask.getCombinedBatchs();
		/*
		 * Element taskElement = new Element("PARTTASK_CANCELCOMBINEBATCH");
		 * taskElement.setAttribute("taskUid", partTask.getTaskUid());
		 * taskElement.setAttribute("partUid", partTask.getPartUid());
		 * taskElement.setAttribute("drawingId", partTask.getDrawingId());
		 * taskElement.setAttribute("partName", partTask.getPartName());
		 * taskElement.setAttribute("batchNum", partTask.getBatchNum());
		 * taskElement.setAttribute("planQty", String.valueOf(partTask
		 * .getPlanQty()));
		 */
		for (SPartTask childPpartTask : combinedBatchs) {
			Element splitTaskElement = new Element("splitTask");
			splitTaskElement.setAttribute("taskUid", childPpartTask
					.getTaskUid());
			splitTaskElement.setAttribute("batchNum", childPpartTask
					.getBatchNum());
			splitTaskElement.setAttribute("planQty", String
					.valueOf(childPpartTask.getPlanQty()));
			/*
			 * taskElement.addContent(splitTaskElement);
			 */
		}
		/*
		 * this.scheduleOperationRecordManager.writeCancelCombineBatchLog(scheme,
		 * partTask); this.scheduleEventManager.writeOperLog(scheme,
		 * ScheduleEvent.EVENTTYPE_PARTTASK_CANCELCOMBINEBATCH, taskElement);
		 */

	}

	// public void addParallelGroup(String scheduleUid, String partTaskUid,
	// List<SOperationTask> opList) throws Exception {
	// ScheduleScheme scheme = getScheduleScheme(scheduleUid);
	// if (scheme == null)
	// return;
	// scheduleOperationTaskManager.addParallelGroup(scheme, partTaskUid,
	// opList);
	//
	// }

	public void updateOperationTasks(String scheduleUid, String parentTaskUid,
			List<SOperationTask> opList, boolean modifyLink) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null)
			return;

		for (SOperationTask operationTask : opList) {
			SOperationTask originalTask = scheme.getAllOperationTaskMap().get(
					operationTask.getTaskUid());
			scheduleOperationTaskManager.updateOperationTask(scheme,
					operationTask);

		}

	}

	public void saveDeviceException(String scheduleUid, String deviceUid,
			List<CalendarData> calendarDataList) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null)
			return;

		SDevice device = scheme.getDeviceMap().get(deviceUid);

		scheduledeviceManager.saveDeviceException(device, scheme, calendarDataList);

	}

	/**
	 * add by zy 更新scheme的工序任务数据，同时保存协作与主制工段数据库的数据
	 * 
	 * @param masterScheduleUid
	 * @param coScheduleUid
	 * @param dataSetOpTask
	 * @throws Exception
	 */
	public void saveMasterCoOperationTask(String masterScheduleUid,
			String coScheduleUid, SOperationTask dataSetOpTask)
			throws Exception {

		ScheduleScheme scheme = getScheduleScheme(coScheduleUid);
		SOperationTask schemeOpTask;
		if (scheme == null)
			return;

		if (dataSetOpTask.getTaskUid() != null) {
			schemeOpTask = scheme.getAllOperationTaskMap().get(
					dataSetOpTask.getTaskUid());

			if (dataSetOpTask.getEstiPreTime() != null)
				schemeOpTask.setEstiPreTime(dataSetOpTask.getEstiPreTime());
			if (dataSetOpTask.getEstiRunTime() != null)
				schemeOpTask.setEstiRunTime(dataSetOpTask.getEstiRunTime());

			scheduleOperationTaskManager.updateOperationTask(scheme,
					schemeOpTask); // dataset中是其它工段的展示，自己工段还是更改不了

		}

		scheduleOperationTaskManager.saveMasterCoOperationTask(
				masterScheduleUid, coScheduleUid, dataSetOpTask); //

	}

	public void saveOperationTasks(String scheduleUid, String parentTaskUid,
			List<SOperationTask> opList, boolean modifyLink) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null)
			return;

		scheduleOperationTaskManager.saveOperationTask(scheme, parentTaskUid,
				opList, modifyLink);

	}

	public void saveVirtualLinks(String scheduleUid,
			List<SVirtualLink> virtualLinkList) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null)
			return;

		scheduleLinkManager.saveVirtualLink(scheme, virtualLinkList);

	}

	public void saveOperationLinks(String scheduleUid,
			List<SOperationLink> operationLinkList) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null)
			return;

		scheduleLinkManager.saveLink(scheme, operationLinkList);

	}

	public void cancelAllCombineBatch(String scheduleUid) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null)
			return;
		schedulePartTaskManager.cancelAllCombineBatch(scheme);

	}

	public void refreshOperationDevice(String scheduleUid, String opUid)
			throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null)
			return;
		scheduleOperationTaskManager
				.refreshOperationDevice(scheme, opUid, null);

	}

	public void RefreshOtherHour(String scheduleUid, String parentTaskUid)
			throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null)
			return;
		scheduleOperationTaskManager.refreshOtherHour(scheme, parentTaskUid);

	}

	public String getNetChartXml(String scheduleUid, String partTaskUid)
			throws Exception {
		// todo
		// 不结构化
		if (scheduleUid == null || scheduleUid.equals("")) {
//			scheduleUid = "schedule-" + SysUtil.getSessionDeptId();
			// parameters.put("scheduleUid", scheduleUid);
		}
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null)
			throw new Exception("找不到调度方案:" + scheduleUid);
		return this.schedulePartTaskManager.getNetChartXml(scheme, partTaskUid);

	}

	public void autoCombineBatch(String scheduleUid) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme != null) {

			this.schedulePartTaskManager.autoCombineBatch(scheme);

		}
	}

	public void deleteAllAssign(String scheduleUid, String deviceUid) {
		List<SOperationTask> deviceTaskList = getDeviceTaskList(scheduleUid,
				deviceUid);
		for (SOperationTask operationTask : deviceTaskList) {
			operationTask.setDevice(null);
			operationTask.setDeviceUid("");
		}
	}

	public void lockAllAssign(String scheduleUid, String deviceUid) {
		List<SOperationTask> deviceTaskList = getDeviceTaskList(scheduleUid,
				deviceUid);
		for (SOperationTask operationTask : deviceTaskList) {
			operationTask.setLocked(1);
		}
	}

	public void unlockAllAssign(String scheduleUid, String deviceUid) {
		List<SOperationTask> deviceTaskList = getDeviceTaskList(scheduleUid,
				deviceUid);
		for (SOperationTask operationTask : deviceTaskList) {
			operationTask.setLocked(0);
		}
	}

	public void deleteAssign(String scheduleUid, String deviceUid,
			String taskUid) {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme != null) {
			SOperationTask operationTask = scheme.getAllOperationTaskMap().get(
					taskUid);
			if (operationTask != null) {

				operationTask.setDevice(null);
				operationTask.setDeviceUid("");
				operationTask.setLocked(0);

			}
		}
	}

	public void clearPreScheduleResult(String scheduleUid) {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme != null) {
			for (SOperationTask operationTask : scheme
					.getScheduleOperationTasks()) {
				if (operationTask.getLocked() != 1) {
					operationTask.setDevice(null);
					operationTask.setDeviceUid("");
				}
			}

		}
	}

	// public void setAssnPriority(String scheduleuid, String deviceuid,
	// String opuid, int priority) {
	// ScheduleScheme scheme = getScheduleScheme(scheduleUid);
	// if (scheme != null) {
	// for (SOperationTask operationTask : scheme
	// .getScheduleOperationTasks()) {
	// if (operationTask.getOpUid().equals(opuid)) {
	// Boolean bFound = false;
	// for (ResourceConstraint resourceConstraint : (operationTask
	// .getAlterResourceMap().values())) {
	// if (deviceuid.equals(resourceConstraint.getDeviceUid())) {
	// resourceConstraint.setPriority(priority);
	// bFound = true;
	// break;
	//
	// }
	//
	// }
	// if (!bFound) {
	// ResourceConstraint nr = new ResourceConstraint();
	// nr.setDeviceUid(deviceuid);
	// // ͬʱ�����豸
	// nr.setDevice(scheme.getDeviceMap().get(deviceuid));
	// nr.setPriority(priority);
	// operationTask.getAlterResourceList().add(nr);
	//
	// }
	// break;
	//
	// }
	//
	// }
	//
	// }
	// }

	public void forceFinish(String scheduleUid, String taskUid)
			throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme != null) {
			SOperationTask operationTask = scheme.getAllOperationTaskMap().get(
					taskUid);
			if (operationTask != null)
				scheduleOperationTaskManager
						.completeTask(scheme, operationTask);
		}
	}

	public void forceAssignToDevice(String scheduleUid, String taskUid,
			String deviceUid) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme != null) {
			scheduleOperationTaskManager.forceAssignToDevice(scheme, taskUid,
					deviceUid);
		}
	}

	public void forceNotAssignToDevice(String scheduleUid, String taskUid,
			String deviceUid) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme != null) {
			scheduleOperationTaskManager.forceNotAssignToDevice(scheme,
					taskUid, deviceUid);
		}
	}

	public Date getScheduleCurrentTime(String scheduleUid) {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme != null) {
			return scheme.getScheduleCurrentTime();
		}
		return new Date();
	}

	public void setScheduleLinkManager(ScheduleLinkManager scheduleLinkManager) {
		this.scheduleLinkManager = scheduleLinkManager;
	}

	public void setScheduleSyncManager(ScheduleSyncManager scheduleSyncManager) {
		this.scheduleSyncManager = scheduleSyncManager;
	}

	/*
	 * 设置调度当前时间
	 */
	public void setScheduleCurrentTime(String scheduleUid,
			Date scheduleCurrentTime) throws Exception {
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme != null) {
			this.scheduleManager.setScheduleCurrentTime(scheme,
					scheduleCurrentTime);
			// scheme.setScheduleCurrentTime(scheduleCurrentTime);
		}
	}

	public void refreshCoOutTask(String scheduleUid) throws Exception {
		// ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		// if (scheme != null) {
		// List<OperationTask> coList= scheme.getScheduleCooperationTaskList();
		// if (scheme != null) {
		// for(ScheduleScheme scheme:this.schemeMap.values())
		// {
		// if(!scheme.getScheduleUid().equals(scheduleUid))
		// {
		// for
		// }
		// }
		//

	}

	public ScheduleSchemeManager() {
		super();
		// 缺省上海表示东八区
		// lqm todo
		// 应该放在整个系统中，避免出现差8小时的问题
		// 一定要注意
		TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
	}

	public Integer getMaxSchemeIdleMinutes() {
		return maxSchemeIdleMinutes;
	}

	public void setMaxSchemeIdleMinutes(Integer maxSchemeIdleMinutes) {
		this.maxSchemeIdleMinutes = maxSchemeIdleMinutes;
	}

	/**
	 * 根据部门号加载调度方案 by hba
	 * 
	 * @param deptId
	 * @return
	 */
	public List<ScheduleScheme> getScheduleSchemeByDeptId(String deptId,
			String schemeType) {
		// TODO Auto-generated method stub
		List<ScheduleScheme> scheduleSchemeList = new ArrayList<ScheduleScheme>();

		scheduleSchemeList = scheduleManager.getScheduleByDeptId(deptId,
				schemeType);
		// schemeMap.put(scheduleUid, scheme);
		// }
		return scheduleSchemeList;
	}

	public Map<String, SchemeActiveControl> getSchemeMap() {
		return schemeMap;
	}

	public void setSchemeMap(Map<String, SchemeActiveControl> schemeMap) {
		this.schemeMap = schemeMap;
	}

	public List<ScheduleScheme> getScheduleSchemeByBaseScheduleUid(
			String baseScheduleUid) {
		List<ScheduleScheme> scheduleSchemeList = new ArrayList<ScheduleScheme>();
		scheduleSchemeList = scheduleManager
				.getScheduleByBaseScheduleUid(baseScheduleUid);
		return scheduleSchemeList;
	}

	public List<SPartTask> canCombinePartTaskFilter(String scheduleUid,
			Map parameters) {

		List<SPartTask> partTaskList = null;
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			// scheme = scheduleManager.getScheduleByUid(scheduleUid);
			// schemeMap.put(scheduleUid, scheme);
		} else {
			if (scheme.getAllPartTaskMap() != null) {
				partTaskList = this.schedulePartTaskManager
						.filterCanCombineBatch(scheme.getSchedulePartTasks(),
								parameters);
			}
		}
		// this.schedulePartTaskManager.sortByPriorityAndSlack(partTaskList);
		this.schedulePartTaskManager.sortByDrawingIdAndBatchNum(partTaskList);
		// 按优先级和松弛率排序临建
		// this.schedulePartTaskManager.sortByPriorityAndSlack(partTaskList);

		return partTaskList;

	}

	/**
	 * 根据父任务号和工序号查找工序 by hba
	 * 
	 * @param scheduleUid
	 * @param parentTaskUid
	 * @param operationIdDesc
	 */
	public SOperationTask getOperationTask(String scheduleUid,
			String partTaskUid, String operationIdDesc) throws Exception {
		// todo
		// 不结构化
		if (scheduleUid == null || scheduleUid.equals("")) {
//			scheduleUid = "schedule-" + SysUtil.getSessionDeptId();
			// parameters.put("scheduleUid", scheduleUid);
		}
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}
		SOperationTask operationTask = new SOperationTask();
		SPartTask partTask = scheme.getAllPartTaskMap().get(partTaskUid);
		if (partTask != null) {
			partTask.sortByOperationId();
			for (SOperationTask o : partTask.getOperationTaskList()) {
				if (!o.isFinished()
						&& o.getOperationIdDesc().equals(operationIdDesc)) {
					return o;
				}
			}
		}
		return null;
	}

	/**
	 * fpc to do 筛选出某外协部门需要加工的调度集合里本部门主制任务的工序 默认取得的是本工段的主制任务的协作工序
	 * 
	 * @param scheduleUid
	 * @param cooperationDeptUid
	 * @param startTime
	 * @param endTime
	 * @return
	 */
	public List<SOperationTask> getCooperationTasksList(String scheduleUid,
			String cooperationDeptUid, Date startTime, Date endTime)
			throws Exception {
		// 不结构化
		if (scheduleUid == null || scheduleUid.equals("")) {
//			scheduleUid = "schedule-" + SysUtil.getSessionDeptId();
		}
		ScheduleScheme scheme = getScheduleScheme(scheduleUid);
		if (scheme == null) {
			throw new Exception("请先打开调度方案!");
		}

		List<SOperationTask> cooperationTasksList = new ArrayList<SOperationTask>();
		Set<SOperationTask> scheduleTaskList = scheme
				.getScheduleOperationTasks();

		for (SOperationTask operationTask : scheduleTaskList) {
			Date planStart = operationTask.getEarlyStart() == null ? operationTask
					.getControlEarlyStart()
					: operationTask.getEarlyStart();
			Date planFinish = operationTask.getLateFinish() == null ? operationTask
					.getControlFinish()
					: operationTask.getLateFinish();

			// 如果本工序计划加工时间不在所选时间段内过滤掉
			if (startTime != null && (planFinish.before(startTime)))
				continue;

			if (endTime != null && (planStart.after(endTime)))
				continue;

			if (operationTask.getDeptUid() != null)
				log.debug("本工序没有加工的部门");

			// 非本部门请制的任务直接过滤掉
			// deptId是请制部门，如果为空则加工该工序的部门是主制部门
			if (operationTask.getDeptUid() != null
					&& (!(operationTask.getDeptUid().startsWith(scheme
							.getDeptUid()))))
				continue;

			// 加工本工序的加工中心在本部门（主制部门）下
			if (scheme.getWorkCenterMap().containsKey(
					operationTask.getWorkCenterUid())
					&& !operationTask.getWorkCenterUid().equals(
							"cooperationCenter"))
				continue;

			// 前台输入部门号为空的话把所有外协工序取出，否则取出工序任务的主制车间等于输入部门号的外协工序
			if (cooperationDeptUid != null
					&& !cooperationDeptUid.equals("")
					&& !cooperationDeptUid
							.equals(operationTask.getMasterShop()))
				continue;

			cooperationTasksList.add(operationTask);
		}

		Collections.sort(cooperationTasksList,
				new Comparator<SOperationTask>() {
					@Override
					public int compare(SOperationTask o1, SOperationTask o2) {

						// TODO Auto-generated method stub
						if (o1.getPlanStart().after(o2.getPlanStart())) {
							return 1;
						} else if (o1.getPlanStart().before(o2.getPlanStart())) {
							return -1;
						}
						return 0;
					}
				});
		return cooperationTasksList;
	}

	private class CoTaskSort {
		private Integer mark;
		private SOperationTask operationTask;

		public Integer getMark() {
			return mark;
		}

		public void setMark(Integer mark) {
			this.mark = mark;
		}

		public SOperationTask getOperationTask() {
			return operationTask;
		}

		public void setOperationTask(SOperationTask operationTask) {
			this.operationTask = operationTask;
		}
	}

	/**
	 * fpc to do 取出主制的零件任务下，需要工序外协的所有部门
	 * 
	 * @param scheduleUid
	 * @return
	 */
	public List<Dept> getCooperationDeptList(String scheduleUid)
			throws Exception {
		// TODO Auto-generated method stub
		DeptDao deptDao = SpringUtils.getBean("deptDao");
		List<Dept> cooperationDeptList = new ArrayList<Dept>();
		List<SOperationTask> cooperationTasksList = this
				.getCooperationTasksList(scheduleUid, null, null, null);

		outer: for (SOperationTask operationTask : cooperationTasksList) {

			for (Dept dept : cooperationDeptList) {
				if (operationTask.getMasterShop().equals(dept.getDeptUid()))
					continue outer;
			}
			cooperationDeptList.add((Dept) deptDao.getById(operationTask
					.getMasterShop()));
		}
		return cooperationDeptList;
	}

	/**
	 * 按照部门和方案类型获取最新活动方案 by hba
	 * 
	 * @param deptUid
	 * @return
	 */
	public List<ScheduleScheme> getDeptActiveSchemesBySchemeType(
			String deptUid, String schemeType) throws Exception {
		List<ScheduleScheme> activeSchemes = new ArrayList<ScheduleScheme>();

		List<SchemeActiveControl> schemeActiveControls = new ArrayList<SchemeActiveControl>();

		for (SchemeActiveControl schemeActiveControl : this.schemeMap.values()) {
			ScheduleScheme scheme = schemeActiveControl.getScheme();
			if (scheme != null && scheme.getSchemeType().equals(schemeType)
					&& scheme.getDeptUid().startsWith(deptUid)) {
				schemeActiveControls.add(schemeActiveControl);
			}
		}
		// 按照逆序排列
		Collections.sort(schemeActiveControls, new Comparator<Object>() {
			public int compare(Object o1, Object o2) {
				SchemeActiveControl schemeActiveControl1 = (SchemeActiveControl) o1;
				SchemeActiveControl SchemeActiveControl2 = (SchemeActiveControl) o2;
				int i = 0;
				// 都是锁定的情况下
				// 优先级越大表示越不重要
				// 同等优先级松弛率越大表示越不重要
				if (schemeActiveControl1.getLastActiveTime().before(
						SchemeActiveControl2.getLastActiveTime())) {
					i = 1;
				}
				return i;
			}
		});

		for (SchemeActiveControl schemeActiveControl : schemeActiveControls) {

			activeSchemes.add(schemeActiveControl.getScheme());
		}

		return activeSchemes;

	}

	/**
	 * 获取任务投料提醒日期 hba
	 * 
	 * @return
	 * @throws Exception
	 */
	public List<String> getWarnDatesBeforeFeed() throws Exception {
		String warnDaysBeforeFeed = "";// SysUtil.getProperty("warnDaysBeforeFeed");
		Integer warnDays = Integer.valueOf(warnDaysBeforeFeed);
		Calendar calendarNow = java.util.Calendar.getInstance();
		calendarNow.set(Calendar.HOUR_OF_DAY, 0);
		calendarNow.set(Calendar.MINUTE, 0);
		calendarNow.set(Calendar.SECOND, 0);
		calendarNow.set(Calendar.MILLISECOND, 0);
		calendarNow.add(Calendar.DAY_OF_YEAR, warnDays);
		List<String> calendarNowList = new ArrayList<String>();
		String year = String.valueOf(calendarNow.get(Calendar.YEAR));
		String month = String.valueOf(calendarNow.get(Calendar.MONTH));
		String day = String.valueOf(calendarNow.get(Calendar.DAY_OF_MONTH));
		calendarNowList.add(year);
		calendarNowList.add(month);
		calendarNowList.add(day);
		return calendarNowList;
	}
}
